Trying to print a file based off the user's input as mentioned in the title. Basically, my program has been altered from one that I previously created which reads data from a file, so I know that the file has been imported correctly (not the problem).
The problem I have is that I'm trying to make the program print the entirety of the .txt file if the user chooses a specific number, in this case '1'. My current code so far is:
import java.io.FileReader;
import java.util.Scanner;
public class InputOutput {
public static void main(String[] args) throws Exception {
// these will never change (be re-assigned)
final Scanner S = new Scanner(System.in);
final Scanner INPUT = new Scanner(new FileReader("C:\\Users\\JakeWork\\workspace\\Coursework\\input.txt"));
System.out.print("-- MENU -- \n");
System.out.print("1: Blahblahblah \n");
System.out.print("2: Blahblahblah \n");
System.out.print("Q: Blahblahblah \n");
System.out.print("Pick an option: ");
if (S.nextInt() == 1) {
String num = INPUT.nextLine();
System.out.println(num);
}
I feel as if my if statement is totally off and I'm heading in the entire wrong direction, could anyone point me in the right and give me a helping hand?
You're close, but not quite there.
You a reading the user input correctly, but now you need the file contents in a loop.
if(S.nextInt() == 1) {
while (INPUT.hasNextLine()) {
System.out.println(INPUT.nextLine());
}
}
This will keep looking as long as the file contents hasNextLine
You can safely remove the String option = S.next();
Also, just a small bit of naming convention nitpicking, don't use all upper case letters for variable names unless they are meant to be static. Also, the first letter of a variable is generally lower case.
if (S.nextInt() == 1) {
// check if there is input ,if true print it
while((INPUT.hasNextLine())
System.out.println(INPUT.nextLine());
}
Also, for menu scenarios like this, consider using a switch statement, then place a call to the menu-printing (that you move to a separate method) in the default case, so that if you enter something wrong, you can reprint the menu choices. Also, the switch statement is more readable (arguably) than a bunch of if's, like this:
int option = S.nextInt();
switch(option) {
case 1 :
while(INPUT.hasNextLine()) {
System.out.println(INPUT.nextLine());
}
break;
case 2 :
//Do stuff
break;
default :
//Default case, reprint menu?
}
}
Related
I am a java beginner, and in this particular problem I practiced making a program that converts any given string to lowercase string. Is there a a better way to achieve this goal in java (in terms of design)?
Also, how does the "else" (after "else if") catches or waits for me to make an input. Somehow that part does not make sense to me, even though I achieved what I wanted. How is the value of "ans" from input transferred to the entire loop and used until the loop is closed?
After many attempts and failures, I used a separate method for the conversion part. My second question is a bit too complicated to be researched.
import static java.lang.System.out;
import java.util.Scanner;
public class MyClass {
public static Scanner s = new Scanner(System.in);
public static String ans;
public static void main(String args[]) {
Conversion();
do {
ans = new String(s.nextLine());
if (ans.equalsIgnoreCase("Y")) {
Conversion();
} else if (ans.equalsIgnoreCase("N")) {
out.println("Thank you for using this program!");
break;
} else {
out.println("Invalid entry!");
out.println("Would you like to convert another string?\n(Please type 'Y' for yes, or 'N' for no.)");
}
} while (ans != "N");
}//END MAIN
public static void Conversion() {
out.println("Please enter string to be converted to lowercase: ");
String str = new String(s.nextLine());
out.println("Your new string is: " + str.toLowerCase());
out.println("Would you like to convert another string? (Y/N)");
}
}
I notice a few issues; Conversion looks like a class-name (Java naming convention would be conversion) and ans != "N" is using == instead of .equals - and wouldn't ignore case (!ans.equalsIgnoreCase("N")). Globals (e.g. static) are bad (pass the Scanner to the methods that need it), and the static import just makes the code more difficult to reason about (in my opinion). Your current loop doesn't really follow a conventional form, I would extract the prompt and loop for "another" conversion to a new method and if you must print a thank you I'd do so after the "main loop". Something like,
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
do {
conversion(sc);
} while (another(sc));
System.out.println("Thank you for using this program!");
}
public static void conversion(Scanner s) {
System.out.println("Please enter string to be converted to lowercase: ");
System.out.printf("Your new string is: %s%n", s.nextLine().toLowerCase());
}
public static boolean another(Scanner s) {
while (true) {
System.out.println("Would you like to convert another string? (Y/N)");
String ans = s.nextLine();
if (ans.equalsIgnoreCase("Y")) {
return true;
} else if (ans.equalsIgnoreCase("N")) {
return false;
}
System.out.println("Invalid entry!");
System.out.println("(Please type 'Y' for yes, or 'N' for no.)");
}
}
Answering your first question:
There are many design patterns and practices so many people can argue what I would recommend you to do. It's basically the same for all programming languages. Let's take your function "Conversion". The name itself says that you use it to convert stuff. Not to display, not to prompt - to convert. In this case, the only actual thing it should do is to convert upperCase to lowercase. In fact, you might want to specify what type of conversion it has in the name of the function (convertToLowerCase?). In fact, in Java, we use lowerCamelCase for all function names and UpperCamelCase for classes.
If you accept my previous suggestion, you could break the Conversion function into multiple ones like promptUserForInput, WrongInputHandler and so forth.
If I understood your second question correctly, you wonder about the way the code executed and how the variable ans is transferred further into the loop. Let's take a look at your code and what variables do:
You initialize your variable in the class MyClass by making it accessible to all methods in the class;
You prompt the user for the input to assign to this variable inside the do..while loop with this line ans = new String(s.nextLine()); which saves the value of the variable and, again, which can be accessed inside the whole class so its value is changed.
It goes into the if..else if...else statement. The way it works, it goes line by line - if the first if-statement fails, it goes on until it finds a truthy statement and it doesn't go any further. In your case, if the ans is not equal to either y/Y/ it will go to else if statement and if it's not n/N, it will go to else (so basically whatever except y/Y/n/N) and will be executed. After that, it jumps into the while (ans!= "N"); line where it compares your class-member variable ans and if it's not equal to "N" it starts over the loop right after the do{ part until you type in the "N".
I hope that makes sense. Whenever the program is asking you for input, it does not execute code further but is stuck until you provide any input. The value from input itself isn't passed throughout the loop and the program. The reason why you can use it because you created a higher-scope variable ans where you saved the result of your input.
IMPORTANT: if you've declared the ans inside the do..while loop, you would've not been able to have accessed it in the while (ans...) because it will 'die' right before the curly brace between do { ...here} while(). If you want to learn more about the scope and variables in general, you can read this article.
Here is my code example:
public static void main(String args[]) {
//declare before entering the loop to have higher scope
String ans = "y";
do {
//we get the given string to convert from the user
String str = promptForString();
//we convert the string
str = converseStringToLowerCase(str);
//display the string (could use another function for that: easier to debug and locate problems and in bigger projects)
out.println("Your new string is: " + str);
//prompt user for respond to continue or not
ans = promptForContinue();
handleResponse(ans);
} while (!ans.equals("n"));
}//END MAIN
//prompts user for an input string
public static String promptForString() {
out.println("Please enter string to be converted to lowercase: ");
String str = new String(s.nextLine());
return str;
}
//converts any given string to lower case
public static String converseStringToLowerCase(String str) {
return str.toLowerCase();
}
//is used to prompt user for reply
public static String promptForContinue() {
out.println("Would you like to convert another string? (Y/N)");
String str = new String(s.nextLine());
//is good to make if...else statements easier - it will always be lower case (or upper if you prefer)
return str.toLowerCase();
}
//easier to locate other response scenarios
public static void handleResponse(String response) {
if (response.equals("n")) {
out.println("Thank you for using this program!");
//it's not a very good practice to innaturally break loops. Use input for that in while(..) statement
// break;
} else if (!response.equals("y")) {
out.println("Invalid entry!");
out.println("Would you like to convert another string?\n(Please type 'Y' for yes, or 'N' for no.)");
}
}
This is the basic setup for a little console-based quiz game. The answers are numbered. I want the player to give the answer number. If the input is not a number, then my program should give a warning, and wait for proper input.
Instead, what I get (after inserting something that is not a number) is an infinite loop of asking the question and presenting the answers again.
public static void main(String[] args) {
boolean quizActive = true;
while(quizActive) {
presentQuestion();
presentAnswers();
Scanner s = new Scanner(System.in);
if (s.hasNext()) {
String choice = s.next();
if (!NumberUtils.isNumber(choice)) {
presentText("Please insert the answer number.");
} else {
System.out.println("You made a choice!");
checkAnswer(choice);
quizActive = false;
}
s.close();
}
}
}
What am I doing wrong here?
If you do not want to question and answers be presented each time move presentQuestion() and presentAnswers() outside the loop.
But main problem is that you closing Scanner.
Remove s.close(); and move Scanner s = new Scanner(System.in); outside of the loop.
I really don't get the point in using scanner for acquiring user input.
The scanner class is perfect to process structured input from a flat file with known structure like an CSV.
But user input need to deal with all the human imperfection. After all the only advantage you get is not needing to call Integer.parseInt() your yourself at the cost to deal with the not cleared input when scanne.nextInt() fails...
So why not using InputStreamReader aside with a loop suggested by others?
Here an Example :
public class Application {
public static void main(String [] args) {
System.out.println("Please insert the answer number. ");
while (true) {
try {
Scanner in = new Scanner(System.in);
int choice = in.nextInt();
System.out.println("You made a choice!");
checkAnswer(choice);
break;
} catch (Exception e) {
System.out.println("Invalid Number, Please insert the answer number ");
}
}
}
}
You started your Quiz in a loop which is regulated by your quizActive boolean. That means that your methods presentQuestion() and presentAnswers() get called every time the loop starts again.
If you don't input a number but a character for example, your program will run the presentText("Please insert the answer number.") and start the loop again. As it starts the loop again, it will call the methods presentQuestion() and presentAnswers().
To stop that, you can do another loop around the input-sequence. Also your Scanner s = new Scanner(System.in) should be outside the loop. And you shouldn't close your Scanner right after the first input and then open it again!
if you want a code example, please tell me :)
I'm currently doing a project in my computer science class and we are suppose to validate each character of a variable to see if it is legal or not. If it starts with a number it's illegal. If it starts with a special character it's legal but bad style. If it has a space it is again illegal. I'll post my current code now:
import java.util.Scanner;
public class classOfValidation {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String theVariable = null;
System.out.println("This program checks the validity of variables");
System.out.println("Please enter a variable (or press 'q' to quit");
theVariable = scan.nextLine();
do {
System.out.println("The variable is illegal");
theVariable = scan.nextLine();
} while (theVariable.startsWith("[0123456789]"));
do {
System.out.println("The variable is illegal");
theVariable = scan.nextLine();
} while (theVariable.contains("[ ]"));
do {
System.out.println("The variable is legal, but has bad style");
theVariable = scan.nextLine();
} while (theVariable.startsWith("[!##$%^&*]"));
}
}
If you couldn't already tell i'm new to programming and as confused as i possibly could be. If you have any advice or anything else you need me to explain then please leave a comment. Thanks everyone
You can use the single regex to validate your input via String#matches() method. But as for the example you've provided, you should use while loop, but not do-while, because in do while case, you are always running it's body once befor condition checked. So, you better do it like:
theVariable = scan.nextLine();
while (theVariable.startsWith("[0123456789]")) {
System.out.println("The variable is illegal");
theVariable = scan.nextLine();
}
while (theVariable.contains("[ ]")) {
System.out.println("The variable is illegal");
theVariable = scan.nextLine();
}
while (theVariable.startsWith("[!##$%^&*]")) {
System.out.println("The variable is legal, but has bad style");
theVariable = scan.nextLine();
}
The second, in your solution, you are using String.startsWith() method and passing into it some regex. Take a look at javadoc for this method. It's said there:
Tests if this string starts with the specified prefix.
That means, that this method doesn't support regexes, but simply checks whether the string starts with the passed string. So, your conditions seems, never to become true. I don't think, someone will input the [0123456789] or [!##$%^&*].
One more, any conditions are checked once, but after that user can modify the input and the previewsly passed condition will not be checked again. Seems, it's better to run into infinite loop with continue and break in some conditions, like:
//infinit loop, until user enter the `q` or the input is correct
while (true) {
//read the input
theVariable = scan.nextLine();
//chtck, whether is `quit` command entered
if ("q".equals(theVariable)) {
break;
}
//if string starts with digit or contains some whitespaces
//then print alert and let the user to
//modify the input in a new iteration
if (theVariable.matches("^\d+.*|.*\s+.*")) {
System.out.println("The variable is illegal");
continue;
}
//if string contains some special characters print alert
//and let the user to modify the input in a new iteration
if (theVariable.matches("^[!##$%^&*].*")) {
System.out.println("The variable is legal, but has bad style");
continue;
}
//if all the conditions checked, then break the loop
break;
}
I think the best way if you are use regex.
Here is an answer how to do that.
I have this code in Eclipse:
package test;
import java.util.Scanner;
class test{
public static void main(String args[]){
Scanner Input = new Scanner(System.in);
if (Input.equals("payday2")){
System.out.println(Input);
}
}
}
Now when I try to start the code/aplication, it terminates itself.
Any ideas why that happens?
You instantiate the Scanner as a variable named Input but never try to read.
Your condition
if (Input.equals("payday2")){
will only check if the Scanner object is equals to the string "payday2" which will always be false, hence the program terminate.
If you want to read, you need to do Input.nextLine().
I dont know about eclipse, but Netbeans would give a warning "equals on incompatible type" with this line.
Also, you should not name your variable with a capital letter as by convention, only class name should start with a capital.
So your fixed program would be
Scanner input = new Scanner(System.in);
String value = input.nextLine();
if ("payday2".equals(value)) {
System.out.println(value);
}
Notice that I kept the string in a variable to display it as displaying input would call toString of the Scanner object which is probably not what you expected.
Notice that I also compared the string in reverse order which is a good practice to avoid NPE even if not really needed here.
You never read input from the Scanner instance so the application doesnt block
String text = input.nextLine();
if ("payday2".equals(text)) {
...
I think you mean to do:
String in = Input.nextLine();
if(in.equals("payday2"))
{
System.out.println(in);
}
Note: in Java 7 you can do the following:
String in = Input.nextLine();
switch(in)
{
case "payday2":
System.out.println(in)
break;
case "payday the heist":
//...
break;
}
Which makes it much easier to manage different input cases.
"if" statement only allows to put numbers in it.
Is there a way to make it read letters?
I'm only in my fifth lesson of Java (I study in a uni and the teacher is very slow but I want to learn things fast)
for example.
import java.util.Scanner;
public class Java {
public static void main (String [] args) {
Scanner scan = new Scanner(System.in);
int answer1;
System.out.println("Do you like Java?");
answer1 = scan.nextInt();
if (answer1 == yes)
System.out.println("Cool ~");
else
System.out.println("Ehh...");
}
}
I want to put "yes" instead of the number 5.
So if the user types "yes" it will print "correct".
P.S. I didn't find a clear answer to that in the search engine.
It's not a duplicated thread as I'm trying to find a clear answer to that.
I need a detailed explanation about it.
I'm still a beginner, using those "high tech java words" won't help me.
You need to modify your program so that your scanner to reads a String instead of an int. You can do that as:
import java.util.Scanner;
public class Java {
public static void main (String [] args) {
Scanner scan = new Scanner(System.in);
String answer1;
System.out.println("Do you like Java?");
answer1 = scan.next();
if (answer1.equals("yes"))
System.out.println("Cool ~");
else
System.out.println("Ehh...");
}
}
I used next() for this since we only want one word (token), but be aware that there are other options for reading Strings.
Notice also that I've changed the test in the condition because it's now a String. See this answer for more on comparing Strings.
You need to modify your program so that your scanner to reads a String instead of an int. You can do that as:
import java.util.Scanner; public class Java {
public static void main (String [] args) {
Scanner scan = new Scanner(System.in);
String answer1;
System.out.println("Do you like Java?");
answer1 = scan.next();
if (answer1.equals("yes"))
System.out.println("Cool ~");
else
System.out.println("Ehh...");
} }
I used next() for this since we only want one word (token), but be aware that there are other options for reading Strings.
Notice also that I've changed the test in the condition because it's
now a String. See this answer for more on comparing Strings.
Ok, what if you want the program to read both words and numbers:
Here's my program (more in depth, when you see the full thing), but this is one of 5 parts (that look a like) where I'm having the program...
public static void Gdr1() {
try {
System.out.print("[Code: Gdr1] Grade 1: %");
Scanner gdr1 = new Scanner(System.in);
Z = gdr1.next();
Z = Double.toString(Grd1);
Grd1 = Double.parseDouble(Z);
if ((Grd1<100)&&(Grd1>=5)) {
Gdr2();
} else if ((Grd1>=100)&&(Grd1<125)) {
System.out.println(" System> Great Job "+Stu+"!");
Gdr2();
} else if (Grd1<5) {
System.out.println("I'm sorry, the lowest grade I am allowed to compute is 5...");
Gdr1();
} else if (Z.equalsIgnoreCase("restart")) {
restart01();
} else {
System.out.println("("+Z+") cannot be resolved in my system...");
Gdr1();
}
} catch (Exception e) {}
}
Now everything works in the program, besides for when the End-User's input = "restart", I know some of the code in the program seems complicated, but it does work (most of it), can anyone help me try to figure this out, its for my portfolio at my school due latest by 1/25/2017 # 11:59 pm.
The things like Z (constant String), ""+Stu+"" (variable input), and [Code: Gdr1] are there for a purpose...