exceptions and infinite loops

2019-07-29 07:06发布

问题:

    // Precondition: number provided is a positive integer
    // Postcondition: returns a integer of length 4
     public static int validateNumber(int num, Scanner scan)
{
    int number = num;
    while(number < 1000 || number > 9999)
    {
        try
        {
            System.out.print("Number must be 4 digits long. Please provide the number again: ");
            number = scan.nextInt();    // reads next integer provided                                      
            scan.nextLine();
        }
        catch(InputMismatchException e) //outputs error message if value provided is not an integer
        {
            System.out.println("Incorrect input type.");
        }
    }
    return number;
}

Assuming the preconditions are met, when this method gets executed and after entering a string to test the program, I get an infinite loop. Why is this problem occurring and how would I fix it?

回答1:

To avoid infinite loop when the exception is thrown, you must skip the current line and move on to the next line for processing. Currently, when the exception is thrown, you are re-iterating and scanning the same line which again throws exception and hence you are stuck in infinite loop.

I think you need to write the scan.nextLine() method call when an exception is thrown.

catch (InputMismatchException e) // outputs error message if value provided is not an integer
            {
                System.out.println("Incorrect input type.");
                // Moved the nextLine() method call over here
                scan.nextLine();
            }

Also modify the logic to detect if the number is 4 digit or not. Use integer comparison using< and > instead of converting the number into string.



回答2:

Why not

number < 1000 || number > 9999

instead of

String.valueOf(number)).length() != 4

It looks much cleaner and is probably more efficient.



回答3:

One problem i can see just see your try catch block carefully-

If you input a non-integer input then scanner.nextInt() will throw an InputMisMatchException and the control will come to catch block so finally a new value is not assigned to the number so again condition met for because its checking with the previous number itself.

Just try if it works if it doesn't then please send your input cases so that we can analyze and also tell us what is the initial value of num in method you are passing.



回答4:

Code looks OK, but consider this instead:

while ((int)Math.log10(number) != 3)