Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this code become an infinite loop? [duplicate]

I wrote this simple code to fetch a double and just keep asking until one was given, but when you give a string it just turns into an infinite loop and I can't figure out why. Any reason why it behaves this way?

Scanner scanner = new Scanner(System.in);   
double x = 0.0d;

while (true) {
    try {
        System.out.println("Gimme a double:");

        x = scanner.nextDouble();
        break;
    } catch (InputMismatchException e) {}           
}

System.out.println(x);
like image 560
Seralize Avatar asked Jun 24 '26 13:06

Seralize


2 Answers

It becomes an infinite loop if an invalid double value is entered initially. Control then enters the exception block. Because Scanner#nextDouble does not consume new line characters, these values are repeatedly passed through to the statement

x = scanner.nextDouble();

which doesn't block having already received input. This results in an infinite loop.

Rather than having an empty exception block, Scanner#nextLine should be used to consume the newline character.

} catch (InputMismatchException e) {
    System.out.println("Error found: " + scanner.nextLine() + " continuing...");
}

such that the Scanner#nextDouble line will block for IO in the next iteration.

like image 54
Reimeus Avatar answered Jun 26 '26 03:06

Reimeus


According to the javadocs for Scanner#nextDouble, the characters are not consumed if the conversion to double is not successful (but they are if the conversion was successful):

Scans the next token of the input as a double. This method will throw InputMismatchException if the next token cannot be translated into a valid double value. If the translation is successful, the scanner advances past the input that matched.

Sample output of your program:

$ java Main
Gimme a double:
3.5
3.5
$ java Main
Gimme a double:
blah
Gimme a double:
Gimme a double:
Gimme a double:
Gimme a double:
Gimme a double:
Gimme a double:
(Infinite loop here)

You must consume the characters yourself, preferably in the exception handler:

} catch (InputMismatchException e) {
    System.out.println("Not a double: " + scanner.nextLine());
}

Sample output of changed program:

$ java Main
Gimme a double:
blah
Skipped Past: blah
Gimme a double:
3.56
3.56
like image 39
rgettman Avatar answered Jun 26 '26 03:06

rgettman



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!