How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
As per the javadoc for Scanner:
When a scanner throws an
InputMismatchException, the scanner
will not pass the token that caused
the exception, so that it may be
retrieved or skipped via some other
method.
That means that if the next token is not an int
, it throws the InputMismatchException
, but the token stays there. So on the next iteration of the loop, reader.nextInt()
reads the same token again and throws the exception again. What you need is to use it up. Add a reader.next()
inside your catch
to consume the token, which is invalid and needs to be discarded.
...
} catch (InputMismatchException e) {
System.out.println("Invalid value!");
reader.next(); // this consumes the invalid token
}
Handling InputMismatchException in a While-Loop
I can't use input2.close() either.
You should never close the Scanner
instance for System.in
as it also closes the System.in
.
I tried using input2.next() at the catch but then he waits for another
input I don't want
Use Scanner::nextLine
instead of Scanner::next
, Scanner::nextInt
etc. Check Scanner is skipping nextLine() after using next() or nextFoo()? to learn why.
Also, try to use do...while
wherever you need to ask the user to enter the data again in case of an invalid entry.
Given below is a sample code incorporating these points:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int option;
boolean valid;
Scanner input2 = new Scanner(System.in);
do {
valid = true;
System.out.println("Choose an option:\n" + "1-Get camera information\n" + "2-Submit Data\n" + "3-Exit");
try {
option = Integer.parseInt(input2.nextLine());
if (option < 1 || option > 3) {
throw new IllegalArgumentException();
}
// ...Place here the rest of code (which is based on the value of option)
} catch (IllegalArgumentException e) {
System.out.println("This is an invalid entry. Please try again.");
valid = false;
}
} while (!valid);
}
}
A sample run:
Choose an option:
1-Get camera information
2-Submit Data
3-Exit
abc
This is an invalid entry. Please try again.
Choose an option:
1-Get camera information
2-Submit Data
3-Exit
6
This is an invalid entry. Please try again.
Choose an option:
1-Get camera information
2-Submit Data
3-Exit
2
Feel free to comment in case of any further doubt/issue.
Unable to handle infinite loop when using Scanner for input
Simply use ob.nextLine()
to ignore it. I fixed the code for you and it works as it should. Your code had several issues which I have mentioned.
import java.util.*;
class HelloWorld {
public static void main(String args[]) {
Scanner ob = new Scanner(System.in);
int t = ob.nextInt();
ob.nextLine();
int a = 0, c = 0;
for (int j = 0; j < t; j++)
{
a = 0; c = 0;
String str = ob.nextLine();
if(str.trim().length()>0){
String [] spstr = str.trim().split("\\s+");
try
{
for (int i=0 ; i<spstr.length ; i++)
{
c = c + Integer.parseInt(spstr[i]);
}
System.out.println(c);
} catch (NumberFormatException e) {
System.out.println("Invalid Input");
}
}
}
}
}
if(spstr[i].equals("")) {i--;}
is pointless and wrong logic in fact which will throw your program into an infinite loop. Simply trim the String and check if it is empty as I have done.- Do not simply catch
Exception
superclass. This is bad for debugging. TheException
raised here isNumberFormatException
which you should catch.
Why am I getting an input Invalid Infinite Loop?
From the Javadoc:
When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
So the "df"
string is still in the Scanner. You have to clear it somehow, by calling next()
or some other means.
Infinite Loop in My Exception Handling?
You can use input.nextLine();
to clear your Scanner in your catch block:
while (!check) {
try {
startingBalance = input.nextDouble();
check = true;
} catch (InputMismatchException e) {
System.out.println("Invalid input!");
input.nextLine();//this will clear your Scanner and repeat again
}
}
Can I ask why you used nextLine() as opposed to nextDouble() ?
because nextLine
move the Scanner to the next line
Catching an InputMismatchException until it is correct
Be aware that When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
To avoid "infinite loop of "Customer IDs are numbers only".", You need to call input.next();
in the catch statement to to make it possible to re-enter number in Console
From
statement
catch (InputMismatchException e) {
System.out.println("Customer IDs are numbers only");
To
catch (InputMismatchException e) {
System.out.println("Customer IDs are numbers only");
input.next();
}
Example tested:
Enter Customer ID: a
Customer IDs are numbers only
b
Customer IDs are numbers only
c
Customer IDs are numbers only
11
Stop infinite Loop when handling invalid user input - Java
This can happen since the nextInt()
doesn't consume the new line character inserted in the buffer when pressed enter to type something in the console.
To overcome this you can add keyboard.nextLine()
to the catch block so you can consume that new line character inserted in the buffer and clear it to the next input.
As others said you should wrap your input hadling in a method since you have louds of nextInt
that won't be catched by your InputMismatchException
. Said method should call the nextInt()
catch the exception if needed and clear the buffer for new line characteres with the nextLine()
if not returns the input by the user.
That way you're guarantee that you will always catching that error.
Related Topics
"No X11 Display Variable" - What Does It Mean
How to Stop Java Process Gracefully
Inner Class Can Access But Not Update Values - Asynctask
How to Redirect Multiple Types of Users to Their Respective Activities
Technically What Is the Main Difference Between Oracle Jdk and Openjdk
Javafx on Linux Is Showing a "Graphics Device Initialization Failed For: Es2, Sw"
Failed to Resolve Com.Google.Android.Gms Play-Services-Auth:11.4.0
Parsing Query Strings on Android
Check Orientation on Android Phone
Why Doesn't "System.Out.Println" Work in Android
Noclassdeffounderror - Eclipse and Android
Difference Between Jsonobject and Jsonarray
How to Ping External Ip from Java Android
How to Request Location Permission At Runtime
Decompiling Dex into Java Sourcecode
Efficiency of Java "Double Brace Initialization"
How to Read Input from the Console Using the Scanner Class in Java