How to Keep a Scanner from Throwing Exceptions When the Wrong Type Is Entered

How do I keep a Scanner from throwing exceptions when the wrong type is entered?

You can use one of the many hasNext* methods that Scanner has for pre-validation.

    if (in.hasNextInt()) {
int a = in.nextInt() ;
System.out.println(a);
} else {
System.out.println("Sorry, couldn't understand you!");
}

This prevents InputMismatchException from even being thrown, because you always make sure that it WILL match before you read it.



java.util.Scanner API

  • boolean hasNextInt(): Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.

  • String nextLine(): Advances this scanner past the current line and returns the input that was skipped.

Do keep in mind the sections in bold. hasNextInt() doesn't advance past any input. If it returns true, you can advance the scanner by calling nextInt(), which will not throw an InputMismatchException.

If it returns false, then you need to skip past the "garbage". The easiest way to do this is just by calling nextLine(), probably twice but at least once.

Why you may need to do nextLine() twice is the following: suppose this is the input entered:

42[enter]
too many![enter]
0[enter]

Let's say the scanner is at the beginning of that input.

  • hasNextInt() is true, nextInt() returns 42; scanner is now at just before the first [enter].
  • hasNextInt() is false, nextLine() returns an empty string, a second nextLine() returns "too many!"; scanner is now at just after the second [enter].
  • hasNextInt() is true, nextInt() returns 0; scanner is now at just before the third [enter].

Here's an example of putting some of these things together. You can experiment with it to study how Scanner works.

        Scanner in = new Scanner (System.in) ;
System.out.println("Age?");
while (!in.hasNextInt()) {
in.next(); // What happens if you use nextLine() instead?
}
int age = in.nextInt();
in.nextLine(); // What happens if you remove this statement?

System.out.println("Name?");
String name = in.nextLine();

System.out.format("[%s] is %d years old", name, age);

Let's say the input is:

He is probably close to 100 now...[enter]
Elvis, of course[enter]

Then the last line of the output is:

[Elvis, of course] is 100 years old

How to stop exception when type in wrong data type using scanner

InputMismatchException from nextInt means the input is not an int. You can catch it.

This will loop until the input is a number between 1 and 6:

do {

try {
guess = sean.nextInt();

if (guess >= 1 && guess <= 6) break;

} catch (InputMismatchException e) {
} finally {
sean.nextLine();
}

System.out.print("Input must be a number between 1 and 6: ");
} while (true);

Side note: calling nextInt will also orphan a new line character, so nextLine advances past it.

Exception Handling with wrong User Input Java

Scanner.nextInt returns ant int, so there is no need to go Object selection = scanner.nextInt(), and then cast to an int, you can merely have int selection = scanner.nextInt() and surround that in a try catch that chatches java.util.InputMismatchException, which is the exception thrown when the user types a letter and not an number

Java.util.scanner error handling

You can use hasNextInt() to verify that the Scanner will succeed if you do a nextInt(). You can also call and discard nextLine() if you want to skip the "garbage".

So, something like this:

Scanner sc = new Scanner(System.in);
while (!sc.hasNextInt()) {
System.out.println("int, please!");
sc.nextLine();
}
int num = sc.nextInt();
System.out.println("Thank you! (" + num + ")");

See also:

  • How do I keep a scanner from throwing exceptions when the wrong type is entered? (java)

The problem with your code, in addition to the unnecessarily verbose error handling because you let nextInt() throw an InputMismatchException instead of checking for hasNextInt(), is that when it does throw an exception, you don't advance the Scanner past the problematic input! That's why you get an infinite loop!

You can call and discard the nextLine() to fix this, but even better is if you use the exception-free hasNextInt() pre-check technique presented above instead.

Java Scanner exception handling

Your program enters an infinite loop when an invalid input is encountered because nextDouble() does not consume invalid tokens. So whatever token that caused the exception will stay there and keep causing an exception to be thrown the next time you try to read a double.

This can be solved by putting a nextLine() or next() call inside the catch block to consume whatever input was causing the exception to be thrown, clearing the input stream and allowing the user to input something again.

Exception handling in Scanner

Any use of methods that throws exceptions should handle, rethrow, or redeclare (if it is a checked exception) them for the next level up to choose what to do with it.

In Scanner, if you take nextDouble() method, it throws various exceptions depending on the status of the scanner. You have to care about it.

But the way to care depend on your program logic.

That said, most exceptions in Scanner are RuntimeException, meaning you don't need to explicitly catch them in your code. Assuming you are in a main, if an exception occurs, it will be handled by at top level by the JVM. I this case, your program will exit with an error code and a stacktrace.

The only exceptions in Scanner which are checked and that you must handle in some way, is when you construct a Scanner from a files. IOException and FileNotFoundException cannot be ignored.


As an example of (abused) usage of exceptions when you read a double, you may be tempted to do:

public static void testScanDoubleWithException() {
Scanner sin = new Scanner(System.in);
System.out.println("Enter a double: ");
while (true) {
try {
double d = sin.nextDouble(); // Throw if not a double
System.out.println("Read double value: "+d);
break;
}
catch (InputMismatchException e) {
System.out.println("Invalid double, shoot again:");
sin.nextLine(); // consume bad input
}
}
sin.close();
}

But the Scanner class provides the more simple/explicit way:

public static void testScanDouble() {
Scanner sin = new Scanner(System.in);
System.out.println("Enter a double: ");
while (!sin.hasNextDouble()) {
System.out.println("Invalid double, shoot again:");
sin.nextLine();
}
double d = sin.nextDouble();
System.out.println("Read double value: "+d);
sin.close();
}


Related Topics



Leave a reply



Submit