Java: Infinite loop using Scanner in.hasNextInt()

2022-09-02 03:03:37

我使用以下代码:

while (invalidInput)
{
    // ask the user to specify a number to update the times by
    System.out.print("Specify an integer between 0 and 5: ");

    if (in.hasNextInt())
    {
        // get the update value
        updateValue = in.nextInt();

        // check to see if it was within range
        if (updateValue >= 0 && updateValue <= 5) 
        { 
            invalidInput = false; 
        } 
        else 
        {
            System.out.println("You have not entered a number between 0 and 5. Try again.");
        }
    } else
    {
        System.out.println("You have entered an invalid input. Try again.");
    }
}

但是,如果我输入“w”,它会告诉我“您输入了无效的输入。“,然后它将进入一个无限循环,显示文本”指定一个介于 0 和 5 之间的整数:您输入了无效的输入。请重试。

为什么会发生这种情况?程序不是应该等待用户在每次到达语句时输入并按 Enter 键吗:

if (in.hasNextInt())

答案 1

在最后一个块中,您需要清除扫描仪中的“w”或其他无效输入。您可以通过调用 Scanner 并忽略其返回值来丢弃该无效输入来执行此操作,如下所示:elsenext()

else
{
      System.out.println("You have entered an invalid input. Try again.");
      in.next();
}

答案 2

问题在于你没有推进过去的有问题的输入。来自 hasNextInt() 文档:Scanner

如果可以使用该方法将此扫描程序输入中的下一个标记解释为默认基数中的值,则返回此值。扫描仪不会前进超过任何输入。trueintnextInt()

所有方法都是如此:它们返回 或 ,而不推进 .hasNextXXX()truefalseScanner

下面是一个用于说明问题的代码段:

    String input = "1 2 3 oops 4 5 6";
    Scanner sc = new Scanner(input);
    while (sc.hasNext()) {
        if (sc.hasNextInt()) {
            int num = sc.nextInt();
            System.out.println("Got " + num);
        } else {
            System.out.println("int, please!");
            //sc.next(); // uncomment to fix!
        }
    }

你会发现这个程序将进入一个无限循环,反复询问。int, please!

如果取消注释该语句,则它将使令牌失败。然后,程序将打印:sc.next()ScannerhasNextInt()

Got 1
Got 2
Got 3
int, please!
Got 4
Got 5
Got 6

失败的检查不会跳过输入的事实是有意的:它允许您在必要时对该令牌执行其他检查。下面是一个示例来说明:hasNextXXX()

    String input = " 1 true foo 2 false bar 3 ";
    Scanner sc = new Scanner(input);
    while (sc.hasNext()) {
        if (sc.hasNextInt()) {
            System.out.println("(int) " + sc.nextInt());
        } else if (sc.hasNextBoolean()) {
            System.out.println("(boolean) " + sc.nextBoolean());
        } else {
            System.out.println(sc.next());
        }
    }

如果运行此程序,它将输出以下内容:

(int) 1
(boolean) true
foo
(int) 2
(boolean) false
bar
(int) 3

推荐