How to Handle Infinite Loop Caused by Invalid Input (Inputmismatchexception) Using Scanner

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");
}
}
}
}
}
  1. 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.
  2. Do not simply catch Exception superclass. This is bad for debugging. The Exception raised here is NumberFormatException 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



Leave a reply



Submit