Uma Kanth
Uma Kanth

Reputation: 5629

Why doesn't scanner ask for an other input in a try-catch while loop java

Suppose I need to keep on asking the user till he enters a double.

What I did is I used a while loop and checking if there is an exception or not.

If there is an exception, I would go and ask for the next input.

double bal = 0;
Scanner sc = new Scanner(System.in);
while (true) {
    try {
        System.out.println("Enter the balance");
        bal = sc.nextDouble();
        break;
        } catch (Exception e) {
          System.out.println("That isn't a number");
    }
}
System.out.println("Bal is " + bal);
sc.close();

But if I enter a non-double then it doesn't ask for the next input, keeps on printing those two lines ending in an infinite loop.

Enter the balance
XYZ
That isn't a number
Enter the balance
That isn't a number
Enter the balance
That isn't a number
Enter the balance
That isn't a number
....

What is that I'm missing?

Upvotes: 3

Views: 531

Answers (3)

Ori Lentz
Ori Lentz

Reputation: 3688

From nextDouble documentation:

If the translation is successful, the scanner advances past the input that matched.

So when the input doesn't match, the scanner does not advance past it. So next iteration when you do nextDouble the input hasn't been cleared and it'll still read the same input.

You should either advance the input by reading next() when you fail or read the input as string and try to parse the result, that way even if the value is illegal, the input has been cleared and next iteration you can read a new value / input:

public static void main(String[] args) {
    double bal = 0;
    Scanner sc = new Scanner(System.in);
    while (true) {
        try {
            System.out.println("Enter the balance");
            bal = Double.parseDouble(sc.next());
            break;
            } catch (Exception e) {
              System.out.println("That isn't a number");
        }
    }
    System.out.println("Bal is " + bal);
    sc.close();
}

Upvotes: 2

Tagir Valeev
Tagir Valeev

Reputation: 100219

Use sc.next() to discard the erroneous input:

while (true) {
    try {
        System.out.println("Enter the balance");
        bal = sc.nextDouble();
        break;
    } catch (InputMismatchException e) {
        System.out.println("That isn't a number");
        sc.next();
    }
}

Also I recommend to catch the specific exception (InputMismatchException in this case). This way you will not erroneously print "That isn't a number" if some other problem occurs (for example, standard input stream is closed).

Upvotes: 5

Zarwan
Zarwan

Reputation: 5797

You need to discard the previous input from the stream by calling sc.next() in your catch block. Sadly, the scanner does not do this automatically when the input fails.

Upvotes: 11

Related Questions