我正在使用以下代码:

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())
有帮助吗?

解决方案

在你的最后else块,你需要清除“W”或扫描仪等输入无效。您可以通过调用扫描仪next(),而忽略它的返回值这样做是为了扔掉无效输入,具体如下:

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

其他提示

但问题是,你没有提前Scanner过去有问题的输入。从 hasNextInt() 文档:

  

返回true如果在此扫描器输入的下一个标记可以解释为在使用int方法默认基数的nextInt()值。的的扫描器不执行任何输入。

这是所有hasNextXXX()方法真:它们返回truefalse,不推进Scanner

下面就来说明这个问题的一个片段:

    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()语句,那么就会使Scanner晃过失败hasNextInt()令牌。然后,程序将打印:

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

此有关非阻断-调用语句由Ben S.是假:

  

另外,hasNextInt()不会阻塞。这是无阻塞的检查,看是否有未来的下一个呼叫可能不阻塞获取输入。

...虽然我不承认,文档很容易被误读给这个意见,名字本身就意味着它被用于此目的。相关报价,与加上强调:

  

在next()和hasNext()方法的和它们的基本类型companion方法(如nextInt()和hasNextInt())首先跳过与分隔符模式匹配的任何输入,然后尝试返回下一个标记。的两者hasNext和next方法可以阻塞等待进一步的输入。 hasNext方法是否嵌段具有到其相关联下一个方法是否将阻止任何连接。

这是一个微妙的点,可以肯定的。无论是说“无论是 hasNext和next方法”或“两者hasnext()和next()”会暗示伴侣的方法将采取不同。但看到他们都遵循相同的命名约定(和文档,当然),它的合理期待他们的行为是相同的,的 hasNext() 明确地说,它可以阻断。

元注:这也许应该是不正确的信息的评论中,但似乎作为一个新的用户,我只能发布这个答案(或编辑,这似乎是首选sytlistic变化维基,而不是那些物质)

标志变量使用起来太容易出错。使用带有注释的显式循环控制。还, hasNextInt() 不阻塞。这是非阻塞检查,看看未来是否 next call 可以在不阻塞的情况下获取输入。如果您想阻止,请使用 nextInt() 方法。

// Scanner that will read the integer
final Scanner in = new Scanner(System.in);
int inputInt;
do {  // Loop until we have correct input
    System.out.print("Specify an integer between 0 and 5: ");
    try {
        inputInt = in.nextInt(); // Blocks for user input
        if (inputInt >= 0 && inputInt <= 5)  { 
            break;    // Got valid input, stop looping
        } else {
            System.out.println("You have not entered a number between 0 and 5. Try again.");
            continue; // restart loop, wrong number
         }
    } catch (final InputMismatchException e) {
        System.out.println("You have entered an invalid input. Try again.");
        in.next();    // discard non-int input
        continue;     // restart loop, didn't get an integer input
    }
} while (true);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top