简体   繁体   English

循环终止

[英]While-loop termination

If I comment out the line garbage = scan.nextLine(); 如果我注释掉那一行,则garbage = scan.nextLine(); , the while-loop runs infinitely. ,while循环将无限运行。 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. 我了解为什么如果只有print命令,它将无限地运行,但是我不完全理解garbage变量的包含是如何阻止它无限运行的。 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. garbage只是一个变量,while循环的“停止”是nextLine()它是一种等待用户输入的方法。 The while doesn't continue until your user inputs something using a keyboard and saves the input into the garbage variable. 直到您的用户使用键盘输入内容并将输入内容保存到garbage变量后,一段时间才会继续。

You need to know two things: 您需要知道两件事:

  • hasNextLine() does not advance the Scanner instance. hasNextLine() 不会使Scanner实例前进。
  • nextLine() does advance the Scanner instance. nextLine() 确实推进了Scanner实例。

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. 您将您的变量捕获到一个名为garbage的变量中,但您可以很容易地调用scan.nextLine()而无需存储结果。 I strongly advise you to read the Javadoc on Scanner to see which methods advance the Scanner instance and which do not. 我强烈建议您阅读Scanner上的Javadoc,以了解哪些方法可以提高Scanner实例的效率,哪些不能。

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. 顺便说一句-从上面的示例中可以看到, garbage是多余的。

If the user inputs an integer, then everything works. 如果用户输入整数,则一切正常。 If they don't, then you get the infinite loop without the garbage = scan.nextLine(); 如果它们不garbage = scan.nextLine(); ,那么您将得到无限循环而没有garbage = scan.nextLine(); line due to the way the Scanner class works. 线是由于Scanner类的工作方式。

When you do something like scan.hasNextInt(); 当您执行诸如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. 因此,如果用户根据您的提示输入了类似“ cat”的内容,那么该输入将在该单词的第一个字母之前暂停。 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. 因为要循环直到输入中有整数,所以不会再读取任何内容,并且将无限循环,因为“ cat”仅位于输入缓冲区中。

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. 通过添加scan.nextLine()您将导致扫描器丢弃所有内容,直到用户按下<enter>并可以处理其他输入为止。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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