简体   繁体   中英

While-loop termination

If I comment out the line garbage = scan.nextLine(); , the while-loop runs infinitely. Otherwise, it does not. I understand why it will run infinitely if there were only the print command, but I don't completely understand how the inclusion of the garbage variable stops it from running infintely. Can someone explain please?

 import java.util.Scanner;

 public class TypeSafeReadInteger
 {
     public static void main(String [] args)
     {
         Scanner scan = new Scanner(System.in);
         String garbage;

         System.out.print("Enter age as an integer > ");

         while (! scan.hasNextInt())
         {
             garbage = scan.nextLine();
             System.out.print("\nPlease enter an integer > ");
         }

         int age = scan.nextInt();
         System.out.println("Your age is " + age);
     }
 }

garbage is just a variable, what 'stops' the while loop is the nextLine() It is a method that waits for user input. The while doesn't continue until your user inputs something using a keyboard and saves the input into the garbage variable.

You need to know two things:

  • hasNextLine() does not advance the Scanner instance.
  • nextLine() does advance the Scanner instance.

By "advance the Scanner instance", I mean "consume" input. Think of input as a stream, and think of a scanner object as something that is consuming that stream.

Things in a normal stream can only be consumed once. You captured your's in a variable called garbage , but you could just as easily have called scan.nextLine() without storing the result. I strongly advise you to read the Javadoc on Scanner to see which methods advance the Scanner instance and which do not.

To fix your code:

    while (!scan.hasNextInt())
    {
        scan.nextLine(); // the order of the lines inside the loop makes the difference!
        System.out.print("\nPlease enter an integer > ");
        // when you perform nextLine() here - you reach the beginning of the loop 
        // without a token in the scanner - so you end up looping forever
    }
    int age = scan.nextInt();

By the way - as you can see from the example above, garbage is redundant.

If the user inputs an integer, then everything works. If they don't, then you get the infinite loop without the garbage = scan.nextLine(); line due to the way the Scanner class works.

When you do something like scan.hasNextInt(); , no characters are actually read from the input. So if a user input something like "cat" in response to your prompt, then the input would be paused just before the first letter of that word. Since you are looping until there is an integer in the input, nothing further is read and you will loop infinitely because "cat" is just sitting in the input buffer.

By adding in the scan.nextLine() you will cause the Scanner to discard everything up to when the user hit <enter> and additional input could be processed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM