如何清除Java中的扫描程序缓冲区?

Leo*_*ang 33 java io

我有这样的事情:

    Scanner in=new Scanner(System.in);
    int rounds = 0;
    while (rounds < 1 || rounds > 3) {
        System.out.print("How many rounds? ");
        if (in.hasNextInt()) {
            rounds = in.nextInt();
        } else {
            System.out.println("Invalid input. Please try again.");
            System.out.println();
        }
        // Clear buffer
    }
    System.out.print(rounds+" rounds.");
Run Code Online (Sandbox Code Playgroud)

我该如何清除缓冲区?

编辑:我尝试了以下,但由于某些原因它不起作用:

while(in.hasNext())
    in.next();
Run Code Online (Sandbox Code Playgroud)

Mak*_*oto 32

试试这个:

in.nextLine();
Run Code Online (Sandbox Code Playgroud)

这使扫描仪进入下一行.

  • 有时输入多行,这仅适用于一行. (3认同)
  • 您可能认为 hasNextLine(或 hasNext)可用于检查是否有更多输入可用,但这在 Java 中不起作用。对于键盘 (System.in),hasNextLine/hasNext 方法始终返回 true。我发现清除所有缓冲数据而不阻塞的唯一方法是打开一个新的扫描仪:in.close(); in = new Scanner(System.in); (2认同)
  • @Georgie 您希望在不关闭旧扫描仪的情况下创建新扫描仪。关闭扫描器也会关闭底层的可读性(在我们的例子中是 System.in),所以如果我关闭一个 System.in 扫描器并创建另一个扫描器,我会在下一次调用 Scanner.next() 时得到 NoSuchElementExceptions。如果你真的需要关闭旧的,[this StackOverflow answer](/sf/ask/1910068331/ close-it) 建议您可以通过为 System.in 创建一个包装器来解决这个问题,如果您想先关闭它。 (2认同)

Ósc*_*pez 11

您无法明确清除扫描仪的缓冲区.在内部,它可以在读取令牌后清除缓冲区,但这是一个超出了porgrammers范围的实现细节.


小智 7

使用以下命令:

in.nextLine();
Run Code Online (Sandbox Code Playgroud)

之后

System.out.println("Invalid input. Please Try Again.");
System.out.println();
Run Code Online (Sandbox Code Playgroud)

或者在下面的花括号之后(你的评论是关于它的).

此命令使扫描器前进到下一行(当从文件或字符串中读取时,这只是读取下一行),因此在这种情况下基本上将其刷新.它清除缓冲区并准备扫描仪以获得新输入.当用户输入无效输入时(例如当被要求输入数字时的字母),它可以优选地用于清除当前缓冲区.

该方法的文档可以在这里找到:http: //docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextLine()

希望这可以帮助!


San*_*Wit 7

其他人建议使用in.nextLine()清除缓冲区,这适用于单行输入。然而,正如评论指出的那样,有时 System.in 输入可以是多行的。

如果您使用的是 System.in 而不是其他一些 InputStream,您可以创建一个新的 Scanner 对象,在其中清除缓冲区。

in = new Scanner(System.in);

如果你这样做,不要in.close()先打电话。这样做将关闭 System.in,因此您将在后续调用in.nextInt();System.in时获得 NoSuchElementExceptions,在您的程序中可能不应关闭。

(上述方法特定于 System.in。它可能不适用于其他输入流。)

如果您确实需要在创建新对象之前关闭 Scanner 对象,则此 StackOverflow 答案建议为 System.in 创建一个 InputStream 包装器,该包装器具有自己的 close() 方法,该方法不会关闭包装的 System.in 流。不过,这对于简单的程序来说太过分了。

  • 创建一个新的扫描仪对象是最好的建议!但是,请确保没有对旧扫描仪对象的引用,以便可以**垃圾收集**。 (3认同)

小智 6

这应该解决它...

Scanner in=new Scanner(System.in);
    int rounds = 0;
    while (rounds < 1 || rounds > 3) {
        System.out.print("How many rounds? ");
        if (in.hasNextInt()) {
            rounds = in.nextInt();
        } else {
            System.out.println("Invalid input. Please try again.");
            in.next(); // -->important
            System.out.println();
        }
        // Clear buffer
    }
    System.out.print(rounds+" rounds.");
Run Code Online (Sandbox Code Playgroud)