Error catching with try-catch and while loop [duplicate] - java

This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed 7 years ago.
I'm trying to make sure that the users input is an integer but when I use the below code I just get an infinite loop of the print statement. Any advice of how to improve?
boolean valid = false;
System.out.println("What block are you gathering? (use minecraft block ids)");
while(valid == false){
try{
block = input.nextInt();
valid = true;
}
catch(InputMismatchException exception){
System.out.println("What block are you gathering? (use minecraft block ids)");
valid = false;
}
}

nextInt() doesn't consume invalid input so it will try read same invalid value over and over again. To solve this problem you need to consume it explicitly by calling next() or nextLine() which accept any value.
BTW to make your code cleaner and avoid expensive operations like creating exceptions you should use methods like hasNextInt() .
Here is how you can organize your code
System.out.println("What block are you gathering? (use minecraft block ids)");
while(!input.hasNextInt()){
input.nextLine();// consume invalid values until end of line,
// use next() if you want to consume them one by one.
System.out.println("That is not integer. Please try again");
}
//here we are sure that next element will be int, so lets read it
block = input.nextInt();

Related

basic Java While(true) question relating to exception handling [duplicate]

This question already has an answer here:
How to use java.util.Scanner to correctly read user input from System.in and act on it?
(1 answer)
Closed 4 years ago.
I have researched while(true) loops for past hour but I was unable to find my answers about this loop.
public class Test {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("Enter Integer: ");
int i = GetAnInteger();
System.out.println("You entered: " + i);
}
public static int GetAnInteger() {
while (true) {
try {
return sc.nextInt();
}
catch (InputMismatchException e) {
sc.next();
System.out.println("That's not an Integer, try again: ");
}
}
}
}
Question 1: We know all the statements in the code will run by the compiler. The purpose of 'while(true)' is to make sure the code runs and it runs indefinitely, the code in the method WILL be executed so why do we need a while(true) loop in the first place?
Question 2: If I remove the 'while(true)' statement, the IDE asks me to create a return statement or make the method as void, why? How does 'while(true)' work in this scenario?
Other posts on Stack Overflow were mostly debating why 'while(true)' is bad or good, I am not interested in this. I am interested in why this code breaks down without 'while(true)' and how do I know when to use 'while(true)' in my other codes?
I searched youtube, java complete reference and stack overflow for past half an hour but couldnt find any answers. This code was taken from "Java for dummies" book and it runs away from explaining the purpose of this while(true) statement.
The purpose of the while(true) is so that it will run until the input is valid and it reaches the return statement. When it reaches the return statement then it will exit the method/loop
This is because there is no guarantee that the try section will be executed. If it isn't then the method needs something to return. You must include a return statement for every possible branch of your method.
Consider the following:
try {
//Oh no! InputMismatchException!!
return sc.nextInt();
//Goes to catch block
} catch (InputMismatchException e) {
sc.next();
System.out.println("That's not an Integer, try again: ");
//executes catch block
}
//Uh oh. Now what? What gets returned?
so why do we need a while(true) loop in the first place?
The while loop allows the user to "try again" if they enter something that isn't an integer. When I run your program, I can do this:
Enter Integer:
this
That's not an Integer, try again:
is
That's not an Integer, try again:
not
That's not an Integer, try again:
an
That's not an Integer, try again:
integer
That's not an Integer, try again:
1
You entered: 1
If I remove the 'while(true)' statement, the IDE asks me to create a return statement or make the method as void, why? How does while(true) work in this scenario?
With the while loop in place, you're guaranteed to eventually return something. Without the while loop, you don't have anything to return if the user doesn't enter an integer. So you have to add something at the end of the method (a default return value, which breaks the intent of the program), or you have to make the method not have a return value at all.
Let's imagine that we delete the while loop, and we add return 0 at the end of the method to make the compiler happy. Now let's try the above scenario again:
Enter Integer:
this
That's not an Integer, try again:
You entered: 0
Obviously this is not what we want!

Java function to get input from scanner until int? [duplicate]

This question already has an answer here:
How to use java.util.Scanner to correctly read user input from System.in and act on it?
(1 answer)
Closed 8 years ago.
I'm attempting to make a java function that returns an int inputted by the user, but won't return until the user inputs a valid number. Here's my initial model of the function:
public int getChoice(){
try{
return scan.nextInt();
}catch(Exception e){
return getChoice();
}
}
scan is declared by Scanner scan = new Scanner(System.in);
This function resulted in a Java.lang.stackOverflowError(hmm... this seems an appropriate website for that...). I figure this is because the function is being constantly called.
I've considered somehow using Integer.valueOf(scan.nextLine())', but the reason I haven't really done anything with it is because at some points, and I can't figure out what determines whether this happens or not, but pressing 'Enter' when the program is calling nextLine() will skip the next nextLine(). I can't really figure out a way around that.
So if anyone could possibly provide me with a Java function that will loop until the user inputs a valid integer, then return that integer, please do so, thank you.
You are getting a bad recursion because the getChoice call inside catch block. To repeat the code indefinitely until the user gives you a valid number use while(true) infinite loop. The code you have to read the line and convert it to Integer it is just fine.
public int getChoice() {
while (true) {
try {
return Integer.valueOf(scan.nextLine());
} catch (Exception e) {
System.out.println("Enter a valid number");
}
}
}

Error handling reading ints from Scanner in while loop

I am try to catch an exception and get it to repeat, but it just creates an endless loop and then crashes the program... why is it doing this? Is it something wrong with my catch?
I have looked around the web and stackoverflow and can only find answers that don't related to what I am trying to achieve.
boolean bError = true;
System.out.println("How many players");
do
{
try
{
PLAYERS = input.nextInt();
if(PLAYERS > 5)
{
System.out.println("maximum of 5");
}//if
else
{
bError = false;
}
}
catch(InputMismatchException e)
{
System.out.println(e);
bError = true;
}
}while(bError && PLAYERS > 5);
It goes into an endless loop if you enter an invalid number because the invalid token is still left on the stream, and nextInt() keeps trying over and over again to grab it.
You will have to get the data off the stream.
One thing you could do is use nextLine() instead, then explicitly try and parse the returned String into an integer (e.g. with Integer.parseInt()).
Another thing you could do is call input.next() (or input.nextLine()) in the exception handler, to read (and discard) the garbage input. You may have to tweak the Scanner delimiters to get next() to work for you if it's not meeting your requirements with default settings.

try/catch infinite loop? [duplicate]

This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed 5 years ago.
Help, I am completely new to java and I am trying to create a loop that will ask for an input from the user which is to be a number. If the user enters anything other than a number I want to catch the exception and try again to get the correct input. I did this with a while loop however it does not give the opportunity after the error for the user to type in anything it loops everything else but that. Please help me to see understand what is wrong and the correct way to do this... Thank you. This is what I have:
import java.util.Scanner;
import java.util.InputMismatchException;
public class simpleExpressions {
public static void main (String[] args) {
Scanner keyboard = new Scanner(System.in);
while ( true ) {
double numOne;
System.out.println("Enter an Expression ");
try {
numOne = keyboard.nextInt();
break;
} catch (Exception E) {
System.out.println("Please input a number only!");
} //end catch
} //end while
} //end main
while ( true )
{
double numOne;
System.out.println("Enter an Expression ");
try {
numOne = keyboard.nextInt();
break;
}
catch (Exception E) {
System.out.println("Please input a number only!");
}
This suffers from several problems:
numOne hasn't been initialized in advance, so it will not be definitely assigned after the try-catch, so you won't be able to refer to it;
if you plan to use numOne after the loop, then you must declare it outside the loop's scope;
(your immediate problem) after an exception you don't call scanner.next() therefore you never consume the invalid token which didn't parse into an int. This makes your code enter an infinite loop upon first encountering invalid input.
Use keyboard.next(); or keyboard.nextLine() in the catch clause to consume invalid token that was left from nextInt.
When InputMismatchException is thrown Scanner is not moving to next token. Instead it gives us opportunity to handle that token using different, more appropriate method like: nextLong(), nextDouble(), nextBoolean().
But if you want to move to other token you need to let scanner read it without problems. To do so use method which can accept any data, like next() or nextLine(). Without it invalid token will not be consumed and in another iteration nextInt() will again try to handle same data throwing again InputMismatchException, causing the infinite loop.
See #MarkoTopolnik answer for details about other problems in your code.
You probably want to use a do...while loop in this case, because you always want to execute the code in the loop at least once.
int numOne;
boolean inputInvalid = true;
do {
System.out.println("Enter an expression.");
try {
numOne = keyboard.nextInt();
inputInvalid = false;
} catch (InputMismatchException ime) {
System.out.println("Please input a number only!");
keyboard.next(); // consume invalid token
}
} while(inputInvalid);
System.out.println("Number entered is " + numOne);
If an exception is thrown then the value of inputInvalid remains true and the loop keeps going around. If an exception is not thrown then inputInvalid becomes false and execution is allowed to leave the loop.
(Added a call to the Scanner next() method to consume the invalid token, based on the advice provided by other answers here.)

How to continue execution of a try catch statement in java [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java: Try-Catch-Continue?
I'm reading in information from a text file and I want my code to throw an exception if there is an invalid type being read. However, I can't figure out how to have my program continue after an exception has been found
while(input.hasNext()) {
try{
type = input.next();
name = input.next();
year = input.nextInt();
} catch(InputMismatchException ex)
{
//System.out.println("** Error: Invalid input **");
//code to make program continue
}
}
You can either just let the thread leave the catch block - code execution will continue after that. If you want to skip the code after the catch block, you can use the continue keyword within a while loop...
If you want to retrieve a year after retrieving the name failed with an exception, then you will have to put a try ... catch around each input.next...() statement. You cannot restart execution at the point the exception has been thrown.

Categories

Resources