'Confusion with an infinite while loop, concerning Scanner.nextInt();

I am having problems with understanding why code is not working. My objective is to keep reading the input of the user until the user finally enters "5", to which the code will continue. I appreciate there are likely better ways, and am open to suggestions of more concise ways to go about this (trying to parse a string, perhaps), however my question is more curious as to why my method does not work as opposed to looking for a better method.

The code works perfectly when any integer is input, however if I were to enter a String, the code loops continuously, and the catch block is always started without any input required. I presume it's a feature of the Scanner retaining my input, but I'm not sure.

My code is the following:

import java.util.Scanner;
import java.util.InputMismatchException;

public class App {
    public static void main(String[] args) {

        int temp = 0;
        System.out.println("Enter the number 5: ");

        while (temp != 5) {
            try {
                temp = sc.nextInt();
            } catch (InputMismatchException e) {
                System.out.println("Try again!");
            }
        }
        System.out.println("Got it!");
        sc.close();
    }
}


Solution 1:[1]

If the next thing to read is not an integer, then nextInt doesn't read anything. So if you type "hi", then nextInt throws an InputMismatchException, and your program calls nextInt again. That call still throws an InputMismatchException, because the next thing to read is still "hi", which isn't an integer. Then your program calls nextInt again, and it throws an exception again for the exact same reason. And so on.

One possible solution is to call sc.next(), and ignore the result:

        try {
            temp = sc.nextInt();
        } catch (InputMismatchException e) {
            sc.next(); // ignore whatever the user typed that wasn't an integer
            System.out.println("Try again!");
        }

Solution 2:[2]

Correct version of code would be like this. Scanner does not know coming input in Int or not. Lets read line and parse it and check if it is integer or not and then continue.

import java.util.Scanner;
import java.util.InputMismatchException;

public class App {
    public static void main(String[] args) {

        int temp = 0;
        System.out.println("Enter the number 5: ");
    Scanner sc = new Scanner(System.in);
        while (temp != 5) {
            try {
        String str = sc.nextLine();
                temp = Integer.parseInt(str);
            } catch (NumberFormatException e) {
                System.out.println("Try again!");
            }
        }
        System.out.println("Got it!");
        sc.close();
    }
}

Solution 3:[3]

Here is what I think is happening:

  1. When you enter an int things work fine. sc.nextInt(); is able to parse the input to an valid integer value.
  2. When you enter string, sc.nextInt(); throws exception, as input string is not a valid integer value.
  3. Now in your code, if the value entered is not integer, the loop will never break as its always (temp != 5) is always true and hence the loop repeats infinitely.

Solution 4:[4]

The infinite loop is because nextInt() is reading numbers only, but not the remaining part of your input, the newline character, which stays inside the input buffer of Scanner.

When your loop calls nextInt() again, it again will recognize the remaining newline character as not an int, the loop again calls nextInt() and ends up in an infinite loop, as described by user253751.

In some situations, sc.next() solves this, but it's not always suitable, as it still won't prevent an infinite loop in a while-loop-scenario.

The better way to solve this is to again instantiate and initialize your Scanner object to flush the input buffer.

        try {
            temp = sc.nextInt();
        } catch (InputMismatchException e) {
            sc = new Scanner(System.in); // flushes the input buffer
            System.out.println("Try again!");
        }

Source:

Java Scanner why is nextLine() in my code being skipped? [duplicate]

How can I clear the Scanner buffer in Java?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user253751
Solution 2 Ravindra babu
Solution 3 Santosh
Solution 4 Kabraxis Luvos