Line of code in while loop executing at wrong time - java

Program code:
public static void main(String[] args) throws IOException {
System.out.print("Welcome to my guessing game! "
+ "Would you like to play (Y/N)? ");
yesOrNoAnswer = (char)System.in.read();
if(yesOrNoAnswer == 'Y') {
System.out.print("\n\nGuess the number (between 1 and 10): ");
while(AnswerIsCorrect == false) {
guess = System.in.read();
if(guess == correctAnswer) {
AnswerIsCorrect = true;
}
else {
System.out.print("\nYou guessed wrong! Please try again: ");
}
}
System.out.print("You guessed correct! Congratulations!"
+ "\n\nPress any key to exit the program . . .");
System.in.read();
}
}
Expected output:
Welcome to my guessing game! Would you like to play (Y/N)? Y
Guess the number (between 1 and 10):
Actual output:
Welcome to my guessing game! Would you like to play (Y/N)? Y
Guess the number (between 1 and 10):
You guessed wrong! Please try again:
When I input 'Y' at the first question (would you like to play) it proceeds to output, "Guess the number between 1 and 10: " This is a good output. However, before I can enter a number, it instantly outputs, "You guessed wrong! Please try again: "
How can I fix this code to achieve the expected output?

The problem lies at your usage of System.in.read().
System.in.read() will read characters one by one and return them as ints. If I enter 1, System.in.read() will return 49 because that's what the character 1 is encoded to.
The reason why it immediately prints that your guess is wrong without letting you type anything is that System.in.read() reads new line characters as well. If there is anything unread, it will read that, instead of asking for new input. There is a new line character after the Y you entered, so it reads that new line character.
You should instead use a Scanner:
Scanner scanner = new Scanner(System.in); // create a new scanner
System.out.print("Welcome to my guessing game! "
+ "Would you like to play (Y/N)? ");
yesOrNoAnswer = scanner.nextLine().charAt(0); // reading the first character from the next line
if(yesOrNoAnswer == 'Y') {
System.out.print("\n\nGuess the number (between 1 and 10): ");
while(AnswerIsCorrect == false) {
guess = Integer.parseInt(scanner.nextLine()); // get an int from the next line
if(guess == correctAnswer) {
AnswerIsCorrect = true;
}
else {
System.out.print("\nYou guessed wrong! Please try again: ");
}
}
System.out.print("You guessed correct! Congratulations!"
+ "\n\nPress any key to exit the program . . .");
scanner.nextLine();
}
Scanner.nextLine() will return the input the user typed as a string and it ignores new line characters.

Related

Ensuring Type-Safe Input Using Nested While-loops

The program that I have written below was designed so that if a user doesn't enter an integer when prompted, the program will loop until they do. This works for the initial check, but the second check does not work. The code is as follows:
import java.util.Scanner;
public class SafeInput
{
public static void main(String[]args)
{
System.out.println("Please enter any integer. If you want to exit, enter -1>");
Scanner scan = new Scanner(System.in);
while(!scan.hasNextInt())
{
String garbage = scan.nextLine();
System.out.println("You've entered garbage.");
}
int input = scan.nextInt();
while(input != -1)
{
System.out.println("\nYou entered: "+input);
System.out.println("Please enter any integer. If you want to exit, enter -1>");
while(!scan.hasNextInt())
{
System.out.println("You've entered garbage.");
String garbage1 = scan.nextLine();
}
input = scan.nextInt();
}
System.out.println("-1 entered. Goodbye");
}
}
Here's what happens when I execute the program:
Please enter any integer. If you want to exit, enter -1>
this is a string
You've entered garbage.
1
You entered: 1
Please enter any integer. If you want to exit, enter -1>
2
You entered: 2
Please enter any integer. If you want to exit, enter -1>
this is also a string
You've entered garbage.
You've entered garbage.
string
You've entered garbage.
1
You entered: 1
Please enter any integer. If you want to exit, enter -1>
2
You entered: 2
Please enter any integer. If you want to exit, enter -1>
-1
-1 entered. Goodbye
Why is it that when I fail the second check for an integer, the program outputs:
You've entered garbage.
You've entered garbage.
Instead of:
You've entered garbage.
Thanks!
second while loop should be updated like below.
while(input != -1)
{
System.out.println("\nYou entered: "+input);
System.out.println("Please enter any integer. If you want to exit, enter -1>");
scan.nextLine();
while(!scan.hasNextInt())
{
System.out.println("You've entered garbage");
String garbage1 = scan.nextLine();
}
input = scan.nextInt();
}
use next() instead of nextLine().
while(input != -1) {
System.out.println("\nYou entered: "+input);
System.out.println("Please enter any integer. If you want to exit, enter -1>");
while(!scan.hasNextInt())
{
System.out.println("You've entered garbage.");
String garbage1 = scan.next();
}
input = scan.nextInt();
}
Look at Scanner#nextLine() java doc,
This method returns the rest of the current line, excluding any line
separator at the end. The position is set to the beginning of the next
line.
See code
Debug:
while(input != -1)
{
System.out.println("\nYou entered: "+input);
System.out.println("Please enter any integer. If you want to exit, enter -1>");
while(!scan.hasNextInt())
{
System.out.println("-- Second -- ");
System.out.println("You've entered garbage.");
String garbage1 = scan.nextLine();
System.out.println(" garbage1 -> " + garbage1);
}
input = scan.nextInt();
}
Output:
Please enter any integer. If you want to exit, enter -1>
q
-- First --
You've entered garbage.
1
-- input --1
You entered: 1
Please enter any integer. If you want to exit, enter -1>
aa
-- Second --
You've entered garbage.
garbage1 ->
-- Second --
You've entered garbage.
garbage1 -> aa
ab
-- Second --
You've entered garbage.
garbage1 -> ab
Just for fun I did some 'enhanced' implementation. It should work correctly.
package example;
import java.util.Scanner;
public class SafeInput {
public static void main(String[] args) {
System.out.println("Please enter any integer. If you want to exit, enter -1>");
try (Scanner scan = new Scanner(System.in)) {
while (true) {
int input = 0;
String garbageOutput = null;
if (scan.hasNextInt() && ((input = scan.nextInt()) != -1)) {
System.out.println("\nYou entered: " + input);
System.out.println("Please enter any integer. If you want to exit, enter -1>");
} else if (scan.hasNextInt() && ((input = scan.nextInt()) == -1)) {
System.out.println("-1 entered. Goodbye");
break;
} else if (!scan.hasNextInt() && (scan.hasNextLine())
&& (!(garbageOutput = scan.nextLine()).isEmpty())) {
System.out.println(String.format("You've entered garbage - [%s]", garbageOutput));
}
}
}
}
}

Why nothing gets printed after while loop?

I am writing a simple bank application. In my program I have used a while loop. In case a user enters wrong input it will re-prompt to enter again.
Now the problem is I am not able to write any system.out.print statement after the loop. It always shows error (says: unreachable statement), and eventually the line doesn't get printed out.
HOW CAN I FIX THIS?
[The reason I need to use system.out.print because I want to print all the info the user has input.]
The program I am working on:
package bankapplication;
import java.util.Scanner;
public class BankApplication {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("WELCOME TO OUR BANK!\n\nPlease give all the inofrmation correctly.");
System.out.println("Enter your name: ");
String name = input.nextLine();
System.out.println("");
System.out.println("Enter your SSN: ");
String ssn = input.next();
System.out.println("");
System.out.println("Enter your Address: ");
String address = input.next();
System.out.println("");
System.out.println("Enter your telephone nr: ");
String teleNum = input.next();
System.out.println("");
while (true) {
System.out.println("Choose an account number for you (Between 5 and 10 positive numbers): ");
int accNum = input.nextInt();
System.out.println("");
if (accNum < 0 && accNum > 10 && accNum < 6) {
System.out.println("Invalid choise!");
} else {
System.exit(0);
}
}
System.out.println("Congratulation! Your new account has been created!");
System.out.println("The following is your account info:\n");
System.out.println("name: " + name + "SSN: " + ssn + "Address: " + address + "Tele. Num: " + teleNum + "Acc num: " + accNum);
}
}
When you invoke System.exit the entire program exits and the process is terminated. Instead you could replace the else statement with:
else { break; }
That will break the current loop and the rest of the statements will be printed. The keyword break simply breaks the loop.
You have a while (true) loop - a loop which is infinite unless something in the loop breaks out of it. The only line you have that breaks out of the loop is System.exit(0), which will end your program entirely. Therefore it is impossible to reach the code after your loop.
If you mean to break out of the loop in your else clause, use a break statement instead of exiting the program.
Note however that your if condition will never be true.
if (accNum < 0 && accNum > 10 && accNum < 6) {
accNum can never be less than zero and greater than 10.
You need to figure out what condition you actually want to check.
the condition
(accNum < 0 && accNum > 10 && accNum < 6)
can never be acheived , there is no way a number can be negative and >10 at the same time...the System.exit(0) will always be called on first loop.
That and when u call System.exit(0) you are exiting the program not the loop, therefor you will never reach the statement you are talking about .
you should either use
break;
or if you would like more prestige, put the right condition in the while(condition) ... try not to get used to using break ;

How do I get this code to loop based off the user's input?

My code here checks whether or not the word that the user inputs is a palindrome or not. It executes properly its just that if the user tries to loop it by pressing "1". The program ends. How do I fix this?
int answer =0;
String original, backwards = "";
Scanner input = new Scanner(System.in);
System.out.println("A palindrome is a word that is the same forwards as it is backwards. Enter a word to check if it is a palindrome or not.");
original = input.nextLine();
int length = original.length();
do {
for ( int i = length - 1; i >= 0; i-- )
backwards = backwards + original.charAt(i);
if (original.equals(backwards))
System.out.println("The entered phrase is a palindrome.");
else
System.out.println("The entered phrase is not a palindrome.");
}
while (answer ==1);
System.out.println("If you would like to check another word press 1. If you wish to exit, press 2.");
answer = input.nextInt();
if (answer ==1){
System.out.println("Enter another word");
}
else if (answer == 2){
System.out.println("Have a nice day");
}
}
}
Here is a sample output of the program:
A palindrome is a word that is the same forwards as it is backwards. Enter a word to check if it is a palindrome or not.
racecar
The entered phrase is a palindrome.
If you would like to check another word press 1. If you wish to exit, press 2.
1
Enter another word
Your loop finishes before the user gets to choose if he wants to enter 1 or 2. It is a do...while loop, so it ends at the while. So it executes only once - because as soon as a palindrome is checked, the next thing is to check whether the answer is 1. But the user has not entered either 1 or 2 at this point.
So you should move the } while ( answer == 1 ) part to the line after the closing of the if...else... that checks what the user answer was.
Also, if the answer was 1, you should ask for another input. The only place you ask for input is before the loop starts. If the user answered 1 you should run original = input.nextLine(); again. Be careful - you may need to run two input.nextLine(), as the scanner will think the rest of the line after the 1 or 2 is what you meant.
Your scanner is asking for nextLine, but you're asking for an int. nextLine means it will take what is typed in the nextLine as a string.
Simple fix is replace 1 and 2 with characters a and b.
Complicated way is to parse string into integer.
make the palindrome check as a method and then call the method if the user input is 1.
In your code , it does not do anything if the user inout is equal to 1.
i just used your scanner objects as it is. You can declare them in your class to use it in all the methods.
public void palindrome(String S){
int answer =0;
String original, backwards = "";
Scanner input = new Scanner(System.in);
System.out.println("A palindrome is a word that is the same forwards as it is backwards. Enter a word to check if it is a palindrome or not.");
original = input.nextLine();
int length = original.length();
do {
for ( int i = length - 1; i >= 0; i-- )
backwards = backwards + original.charAt(i);
if (original.equals(backwards))
System.out.println("The entered phrase is a palindrome.");
else
System.out.println("The entered phrase is not a palindrome.");
}
while (answer ==1);
System.out.println("If you would like to check another word press 1. If you wish to exit, press 2.");
int option= input.nextInt();
if (option==1){
System.out.println("Enter another word");
String word= input.readLine();
palindrome(word);
}
You need to put the check if user want to enter another work in the while loop. But in the mean time, be careful to reset all variables to their original value, so it might be best to set them in the while loop as well. Something like this:
import java.util.Scanner;
public class Palidrome {
public static void main(String[] args) {
int answer = 0;
Scanner input = new Scanner(System.in);
String original;
System.out
.println("A palindrome is a word that is the same forwards as it is backwards. Enter a word to check if it is a palindrome or not.");
while( true ) {
original = input.nextLine();
String backwards = "";
int length = original.length();
for (int i = length - 1; i >= 0; i--)
backwards = backwards + original.charAt(i);
if (original.equals(backwards))
System.out.println("The entered phrase " + original + " is a palindrome.");
else
System.out.println("The entered phrase " + original + " is not a palindrome.");
System.out.println("If you wish to exit, press 2");
answer = input.nextInt();
if(answer == 2) {
System.out.println("Have a nice day");
break;
}
input.nextLine();
System.out.println("Enter another word");
}
input.close();
}
}
A do while loop works the same way as a regular while loop, except the first conditional check is omitted. If the condition in your while was met, then execution of the code in the do block would be continued. However, the while condition is never met, can you see why? Even if this condition was met, that's not the code you wanted executed next. The code below while is not a part of the do-while loop. You need to move the while to come after both of your conditional blocks at the end. The Java docs on while loops should be a useful read.

Problems with try-catch inside while loop in Java

I'm new here and I'm learning Java. In one of my programs, I have made a guessing game. The guessing game is supposed to keep asking the user to input a guess until they guess the number right.
This is my code:
import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
final int minValue = 1;
final int maxValue = 10;
final boolean displayHints = true; // Display whether the number is too high or too low when guessed incorrectly?
int tries = 1;
int guess = 0; // We need to give 'guess' a (temporary) value or else the 'while' loop will create an error
boolean error = false;
Random generator = new Random(); // Create scanner 'generator'
int random = generator.nextInt(maxValue) + minValue; // Define 'random' variable with a random value
if (random == guess) { // In case 'random' = 'guess'
guess = -852654;
}
Scanner input = new Scanner(System.in); // Create a scanner
System.out.println("Random number: " + random); // Hey, no cheating! (for debugging purposes)
System.out.println("Try to guess the magic number! (from " + minValue + " to " + maxValue + ")");
while (random != guess) {
do { // Supposed to ask the user to input a number until they enter a valid number. This is the part of the code that is not working.
System.out.println("\nInput your guess now!");
try {
guess = input.nextInt();
error = false;
} catch (InputMismatchException e) {
System.err.println("That's not a number!\n");
error = true;
continue;
}
} while (error);
if (guess == random) {
System.out.println("Correct!");
System.out.println("Number of tries: " + tries + ".");
input.close();
} else {
tries++;
if (displayHints) {
if (guess < random) {
System.out.println("Sorry, too low!");
} else if (guess > random) { // not strictly necessary
System.out.println("Sorry, too high!");
}
} else {
System.out.println("Sorry, that was not the right number");
}
}
}
}
}
The code is pretty self-explanatory, because I made a lot of comments. The problem, though, is when the user enters an invalid integer (like 'banana'), instead of saying "That's not a number!" and asking for another number, the code does something like this:
Random number: 9
Try to guess the magic number! (from 1 to 10)
Input your guess now!
banana
Input your guess now!
Input your guess now!
Input your guess now!
Input your guess now!
Input your guess now!
Input your guess now!
Input your guess now!
Input your guess now!
Input your guess now!
Input your guess now!
That's not a number!
Input your guess now!
That's not a number!
That's not a number!
That's not a number!
That's not a number!
That's not a number!
That's not a number!
That's not a number!
That's not a number!
That's not a number!
That's not a number!
That's not a number!
Input your guess now!
That's not a number!
Input your guess now!
That's not a number!
Input your guess now!
That's not a number!
Input your guess now!
That's not a number!
Input your guess now!
That's not a number!
Input your guess now!
That's not a number!
The rest of the code works perfectly.
As explained by rgettman you need to consume the erroneous input, since if InputMismatchException is risen, the token is not consumed.
An alternative solution, to save you from the try/catch block would be to use hasNextInt():
if (input.hasNextInt())
{
int guess = input.readInt();
}
else
{
if (input.hasNextLine())
input.nextLine();
}
You forgot to consume the bad input. Try consuming the line with the bad input in the catch block.
} catch (InputMismatchException e) {
System.err.println("That's not a number!\n");
error = true;
String notANumber = input.nextLine(); // add
continue;
}
Also, println already adds a newline character at the end of whatever is printing, so there is no need to add additional \n characters to the strings you're printing.
With the above change, here's sample input/output of the do-while loop:
Input your guess now!
banana
That's not a number!
Input your guess now!
8
The scanner never actually gets a valid input, so it is repeatedly grabbing banana over and over when you reach guess = input.nextInt();
My fix would be to instead read in the input as a string and parse it to an integer. You would then just need to catch a NumberFormatException instead of a InputMismatchException
This is how I would do it:
try {
guess = Integer.parseInt(input.next());
error = false;
} catch (NumberFormatException e) {
System.err.println("That's not a number!\n");
error = true;
}
The easiest way is just to change
guess = input.nextInt();
to
guess = Integer.valueOf(input.next());
That will solve the problem, only with changing one small line of code. Copy and try it!
But I still think your code looks messy. I would do something like this
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
Random r = new Random ();
int x = r.nextInt(10);
int y = 0;
int counter=0;
do{
System.out.println("Guess a number between 0-10: ");
try{
y = Integer.valueOf(input.next());
}catch (Exception e){
System.out.println("That is not a number ");
continue;
}
counter ++;
if (counter>5){
System.out.println("So you still don't know how to guess quicker?");
}
if (y<x){
System.out.println("You gessed wrong, the number is higher");
}
else if (y>x){
System.out.println("You gessed wrong, the number is lower");
}
else if (y==x)
System.out.println("You gessed right, the number is: " + x);
}while(y!=x);
System.out.println("You guessed the number in: " + counter + " times");
if(counter <=4){
System.out.println("You found out how to guess the number quickly");
}
}
As many have mentioned, you need to consume the erroneous input. I was having a very similar problem, and I didn't see an appropriate response here, but I found one elsewhere.
Try putting the following line at the end of your catch block.
input.nextLine();
This will clear the buffer and should fix your problem.

Do while loop not printing correctly after 1st loop

I am trying to do a do-while loop that makes the program iterate again after the user inputs "y" or "Y", but everytime i run the program, It prints out something like this:
Would you like to try again?
Enter Y for yes or N for no: [DrJava Input Box] (I enter y)
Are you a student? (no input box is shown, and it skips it)
Are you a member of staff or faculty? [DrJava Input Box] (i enter yes or no)
How many tickets do you need? [DrJava Input Box] (I enter an int, but it doesnt complete that part where it shows how many tickets sold or how much it costs)
Would you like to try again?
Enter Y for yes or N for no: [DrJava Input Box]
this is what my program looks like:
import java.util.Scanner;
public class Ticket
{
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
double ticketprice = 12.00;
double result;
double result2;
double result3;
char repeat;
String input;
String student;
String staff;
int ticket;
do
{
System.out.println("Are you a student?");
student = keyboard.nextLine();
System.out.println("Are you a member of staff or faculty?");
staff = keyboard.nextLine();
System.out.println("How many tickets do you need?");
ticket = keyboard.nextInt();
if(student.equals("yes"))
{
System.out.println("Here is your " + ticket + " tickets for $0.00");
}
if(staff.equals("yes"))
{
result = ticketprice * .85;
result2 = ticket * result;
System.out.printf("Here are your " + ticket + " tickets for $%.2f\n", result2);
}
if(student.equals("no") && staff.equals("no"))
{
result3 = ticket * ticketprice;
System.out.printf("Here are your " + ticket + " tickets, for $%.2f\n", result3);
}
System.out.println("Would you like to try again?");
System.out.print("Enter Y for yes or N for no: ");
input = keyboard.next();
repeat = input.charAt(0);
}
while(repeat == 'y' || repeat == 'Y');
}
}
i am a beginner to programming, so any help would be good. Thank you.
At the end of the loop you call next() to read the "try again" response. This reads the next token, but still leaves the line ending on the input stream.
Next time through the loop, when you call nextLine() to read the "are you a student" response, it simply reads the remainder of that line immediately.
The easiest solution is:
Use nextLine() instead of next() for your "try again" prompt, but then this means you'll have to take care of the line ending left by nextInt() in the "tickets" question, so then you'll also have to...
Use nextLine() instead of nextInt() for your "tickets" question, then use Integer.parseInt() to parse the string into an int.
An alternate option, since all your responses seem to be just single-word responses, is to use next()/nextInt() everywhere and not use nextLine() at all. The point is, when you mix the two, you have to be aware of how they interact.
The issue lies in this block of code:
System.out.println("Would you like to try again?");
System.out.print("Enter Y for yes or N for no: ");
input = keyboard.next();
repeat = input.charAt(0);
When you call keyboard.next(), it doesn't read the entire line, so when your program loops again, the next time you call keyboard.nextLine(), it takes in part of what you entered previously in the loop and it gets ahead of itself.
The best solution would be to add a keyboard.nextLine() after you call keyboard.next() so that the remainder of the line will be consumed and won't be left over to mess up future iterations of the loop.
So for example you could change it like this:
System.out.println("Would you like to try again?");
System.out.print("Enter Y for yes or N for no: ");
input = keyboard.next();
keyboard.nextLine();
repeat = input.charAt(0);

Categories