Why is try-catch-finally not re-prompting the user? - java

I am relatively new to Java and all programming in general. I'm writing a simple GuessNumber program for school. The user enters a number 1-10 and it is compared to a random number 1-10. The req spec states that all invalid input should be checked and the user should be re-prompted if invalid input is found. I am using try-catch-finally for this. My catch block finds the exception for int guess if it is indeed not an integer, but it does not re-prompt the user, and instead keeps the initial value of 0. I only initialized guess before user input because the terminal repeatedly yelled at me about it until I did. I am also not sure why the variable must be initialized before the try block.
I looked all over but every solution I've found has code nearly identical to mine in structure. I'm guessing this must be something that I simply am not familiar with/others neglect to mention because it is so elementary. This is my first time using try-catch-finally by the way.
int guess = 0;
int number = (int)((Math.random()*10) + 1);
System.out.print("Please guess a number between 1 and 10, inclusive: ");
//open try
try(BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
guess = Integer.parseInt(br.readLine());
//monitor input
while(guess < 1 || guess > 10) {//open while
System.out.print("You seem to have entered something wrong. Please only");
System.out.println(" enter ");
System.out.print("an integer number between 1 and 10, 1 and 10 included: ");
guess = Integer.parseInt(br.readLine());
}//close while
//close try
} catch(NumberFormatException e) {//open catch
System.out.print("You seem to have entered something wrong. Please only");
System.out.println(" enter ");
System.out.print("an integer number between 1 and 10, 1 and 10 included: ");
//close catch
} finally {//open finally
//user feedback
if(number == guess){
System.out.println("You got it! You guessed the number correctly. It is "
+ number + ".");
} else {
System.out.println("I'm sorry! That is not the number I was thinking of.");
System.out.println("You guessed " + guess + ", but the number is "
+ number + ".");
}
}//close finally
If the user enters an exclamation point ! for example, the program does out put the catch block code. However, it then moves on with 0 as the guess and runs the rest of the program, and ends. The program works correctly if an integer is entered, however. Any input is greatly appreciated!
EDIT: I deleted the finally block, and threw the try-catch blocks inside a while loop with a boolean variable boolean done = false; with the condition while(!done) if the try is successful, it sets done = true; and the program ends. That wasn't good enough and I had infinite looping from exceptions, so I threw some continue; statements at the end of the catch blocks and that worked. Can anyone explain why the continue statements were necessary/how they affect the flow of the program?
//init vars needed
int guess;
int number = (int)((Math.random()*10) + 1);
boolean done = false;
System.out.print("Please guess a number between 1 and 10, inclusive: ");
while(!done) {//open while
try {//open try
guess = Integer.parseInt(br.readLine());
while(guess < 1 || guess > 10) {
System.out.print("You seem to have entered something wrong. Please only");
System.out.println(" enter ");
System.out.print("an integer number between 1 and 10, 1 and 10 included: ");
guess = Integer.parseInt(br.readLine());
}
if(number == guess) {
System.out.println("You got it! You guessed the number correctly. It is "
+ number + ".");
} else if(number != guess) {
System.out.println("I'm sorry! That is not the number I was thinking of.");
System.out.println("You guessed " + guess + ", but the number is "
+ number + ".");
}
done = true;
} //close try
catch(NumberFormatException e) {//open catch
System.out.print("You seem to have entered something wrong. Please only");
System.out.println(" enter ");
System.out.print("an integer number between 1 and 10, 1 and 10 included: ");
continue;
}//close catch
catch(IOException e) {//open catch
System.out.print("You seem to have entered something wrong. Please only");
System.out.println(" enter ");
System.out.print("an integer number between 1 and 10, 1 and 10 included: ");
continue;
}//close catch
}//close while

An exception thrown from parseInt causes your loop to break. You probably want your loop to contain a try-catch-finally clause, and not vice-versa.

You should organize your code, first as other coments said you should execute your code in try and handle the exceptions on the catch, finally is redundant if you are going to execute in the try block. Use this as an example, you also have another question where they can explain better than me. Hope it helped.
[link] Does a finally block always get executed in Java?
try {
System.out.println("Im the try block");
}
finally {
System.out.println("Im the finally block");
}
Output:
Im the finally block
Im the try block
Also NumberformatException is going to work when you put a number but you missed the IOException I think.

Finally section will happen anyway, regardless of exception or not.
you should put the code from the finally section in the try section.

Related

Exception handling with a do-while loop in Java

The algorithm should take in 3 integers to an ArrayList. If the input is not an integer, then there should be a prompt. When I execute my code the catch clause is executed, but the program runs into a infinite loop. Could someone guide me into the right direction, I appreciate the help. :-D
package chapter_08;
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class IntegerList {
static List<Integer> numbers = new ArrayList<Integer>();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int counter = 1;
int inputNum;
do {
System.out.print("Type " + counter + " integer: " );
try {
inputNum = input.nextInt();
numbers.add(inputNum);
counter += 1;
}
catch (Exception exc) {
System.out.println("invalid number");
}
} while (!(numbers.size() == 3));
}
}
That is because when the next int is read using nextInt() and it fails, the Scanner still contains the typed contents. Then, when re-entering the do-while loop, input.nextInt() tries to parse it again with the same contents.
You need to 'flush' the Scanner contents with nextLine():
catch (Exception exc) {
input.nextLine();
System.out.println("invalid number");
}
Notes:
You can remove the counter variable, because you're not using it. Otherwise, you could replace counter += 1 by counter++.
You can replace while (!(numbers.size() == 3)) with while (numbers.size() != 3), or even better: while (numbers.size() < 3).
When catching exceptions, you should be as specific as possible, unless you have a very good reason to do otherwise. Exception should be replaced by InputMismatchException in your case.
If inputNum = input.nextInt(); cannot be fit into an int and a InputMismatchException is raised, the input of the Scanner is not consumed.
So after the catch, it loops and it goes again here :
inputNum = input.nextInt();
with exactly the same content in the input.
So you should execute input.nextLine(); in the catch statement to discard the current input and allow a new input from the user.
Besides it makes more sense to catch InputMismatchException rather than Exception as other exception with no relation with a mismatch could occur and it would not be useful to display to the user "invalid number " if it is not the issue :
catch (InputMismatchException e){
System.out.println("invalid number ");
input.nextLine();
}
You should to use a break; in your catch(){} like so :
try {
inputNum = input.nextInt();
numbers.add(inputNum);
counter += 1;
} catch (Exception e) {
System.out.println("invalid number ");
break;
}
So if one input is not correct break your loop.
try changing
inputNum = input.nextInt();
to
String inputText=input.next();
inputNum = Integer.valueOf(inputText);
it works perfectly well.
You need to move the scanner to the next line. Add this line of code below the error message in the catch section.
input.nextLine();

WHILE Loop Condition Does Not Validate Input

I have a WHILEloop which checks for marks for a particular student. However, it does not loop if the value is invalid (input less than 0 and more than 100):
int marks= -1;
System.out.print("Student Marks (/100): ");
while (((marks< 0) || (marks> 100))) {
try {
marks = Integer.parseInt(sc.nextLine());
break;
} catch (NumberFormatException nfe) {
System.err.println("Error: Invalid Mark(s)");
System.out.print("Student Marks (/100): ");
}
}
It does catches exception if characters other than numbers are entered.
But it does not loop again if value if less than 0 or more than 100.
I have tried making many changes to it but to no result.
Any help given is appreciated!
You should remove the break statement, since it breaks you out of the loop regardless of what value of marks was input.
Always use continue instead of break if you want to keep the loop running.
You may check the marks inside the while loop with an if condition and here you may use break -
import java.util.Scanner;
public class TakeInput{
public static void main(String args[]){
int marks= -1;
Scanner sc = new Scanner(System.in);
System.out.print("Student Marks (/100): ");
while (sc.hasNext()) {
try {
marks = Integer.parseInt(sc.nextLine());
if(marks<0 || marks>100){
break;
}
//do something
// with the marks
//take new marks
System.out.print("Student Marks (/100): ");
} catch (NumberFormatException nfe) {
System.err.println("Error: Invalid Mark(s)");
System.out.print("Student Marks (/100): ");
}
}
}
}
Now as long as you enter anything except a number n when n<0 || n>100 will continue the loop. Any NumberFormatExeption take you to the catch block.
If you enter 34 then it goes to the while block and prompt for a next number.
Then if you enter 56 then it dose the same thing.
When you enter any String rather than a number than it goes to the catch block
This process continues until you enter a invalid number (n>100 || n<100). Pressing Ctrl+C also exit you from the loop.
Hope it will help you.
Thanks a lot.

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 ;

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.

Try-Catch inside While Loop

The code below asks the user how many racers he/she would like.
while (true) { // loops forever until break
try { // checks code for exceptions
System.out.println("How many racers should" + " participate in the race?");
amountRacers = in.nextInt();
break; // if no exceptions breaks out of loop
}
catch (InputMismatchException e) { // if an exception appears prints message below
System.err.println("Please enter a number! " + e.getMessage());
continue; // continues to loop if exception is found
}
}
If a number is entered at amoutnRacers = in.nextInt(); the code breaks out of the loop and the rest of the program runs fine; however, when I enter something such as "awredsf" it should catch that exception, which it does. Instead of prompting the user again it loops continuously, which to me does not make sense.
The program prints like this when looping continuously:
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?
How many racers should participate in the race?Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
Please enter a number! null
...
I do not understand what is going on amountRacers = in.nextInt(); so why is the user not able to enter a number?
Just add input.next() once you catch InputMismatchException.
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Please enter a number! " + e.getMessage());
input.next(); // clear scanner wrong input
continue; // continues to loop if exception is found
}
You need to clear the wrong input, which scanner automatically does not.
Today i solved this problem :-) This is my code. I think that i help
public int choice () throws Exception{
Scanner read = new Scanner(System.in));
System.out.println("Choose the option from the upper list");
int auxiliaryChoiceMenu = 5;
int auxiliaryVariable = -1;
boolean auxiliaryBoolean = false;
while (!auxiliaryBoolean) {
try {
auxiliaryVariable = read.nextInt();
read.nextLine();
} catch (Exception e) {
System.out.println("incorrect data, try again"+e);
read.nextLine();
continue;
}
if (auxiliaryVariable<0 || auxiliaryVariable>auxiliaryChoiceMenu){
System.out.println("incorrect data, try again");
} else {
auxiliaryBoolean = true;
}
choiceMenu = auxiliaryVariable;
}
return choiceMenu;
//choicemenu is a external variable
}
You may need to create a Scanner class for getting standard input streamed from the keyboard. You should have a statement somewhere in your code that creates an instance of a Scanner class like: Scanner in = new Scanner(System.in);
so the " in " variable in your statement: amountRacers = in.nextInt(); waits and scans for entered input from the keyboard and stores it.
Why use a loop with a try and catch?
My advice would be to always use a try and catch with either a while or do while loop, so you can ask the user to repeat his/her input. It also depends which loop you already use and/or on how your code is structured.
For example if you already have a do while loop then I would advice you to simply adjust/modify your existing loop.
I will post some examples on how you can use a try and catch with a loop to repeat the input after a user has provided a wrong one.
See examples below:
Example 1
Scanner input = new Scanner(System.in);
int exampleInput = 0;
do {
try {
System.out.print("\nEnter an integer from 1 to 25: ");
exampleInput = input.nextInt();
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer from 1 to 25");
input.next(); // Clear scanner buffer of wrong input
}
} while (exampleInput < 1 || exampleInput > 25);
System.out.println("Print exampleInput: " + exampleInput);
Example 2
Scanner input = new Scanner(System.in);
int exampleInput; // Here you don't need to initialize this variable because you don't need it as a condition for the loop.
boolean isDone = false;
do {
try {
System.out.print("\nEnter an integer: ");
exampleInput = input.nextInt();
isDone = true;
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer");
input.next(); // Clear scanner buffer of wrong input
}
} while (!isDone);
System.out.println("Print exampleInput: " + exampleInput);
Example 3
Scanner input = new Scanner(System.in);
int exampleInput; // Here you don't need to initialize this variable because you don't need it as a condition for the loop.
boolean isDoneLoop2 = false;
while (!isDoneLoop2) {
try {
System.out.print("\nEnter an integer: ");
exampleInput = input.nextInt();
isDoneLoop2 = true;
}
catch (InputMismatchException e) { //if an exception appears prints message below
System.err.println("Wrong input! Enter an integer");
input.next(); // Clear scanner buffer of wrong input
}
}
System.out.println("Print exampleInput: " + exampleInput);
This works for me.
while (true) {
try {
System.out.print("Ingrese la cantidad de puestos de atenciĆ³n: ");
int puestos = Integer.parseInt(scn.nextLine());
break;
}
catch (NumberFormatException e) {
System.out.println("Ingrese un valor correcto");
scn.reset();
continue;
}
}

Categories