如何在 java 中使用输入整数的额外条件实现 hasNextInt()

how to implement hasNextInt() in java with extra conditions on the input integer

我遇到了与此相同的问题 question,我需要确保用户输入的是一个整数并且还包含 7 位数字,而我认为需要 0 到 150 之间的整数:

我试过了

System.out.print("Please enter your ID without any spaces (7 digits): ");
        while (in.hasNextInt() == false || in.nextInt()/1000000 == 0 || in.nextInt()/10000000 > 0) 

// division with two integers by a million, if you had less than 7 digits would give zero
// division with two integers by ten million, if you had more than 7 digits would give you greater than zero
        {
            in.next();
            System.out.print("Please enter your ID without any spaces (7 digits): ");
        }
        student_ID = in.nextInt();


// Sample Output:

Please enter your ID without any spaces (7 digits): 123 

然后它就停在那里,即使我后面还有其他打印语句。如果我只是在 while 的括号中包含 in.hasNextInt() 部分,它就单独工作,但是我不知道如何向 while 循环添加更多条件 (提示用户直到他们输入 7 位数字 整数 ),我也尝试使用 do loop,但没有成功。

p.s。我知道 student_ID 前面没有 int 我在我的代码中声明它是一个整数变量所以不用担心 :)

你在程序中犯了很多逻辑错误。让我们逐行检查。在提示用户输入 7 位数字后。你进入 while 循环。

while (in.hasNextInt() == false || in.nextInt()/1000000 == 0 || in.nextInt()/10000000 > 0)

假设您键入 123 并按回车键。这个 123 将被扫描器对象 in 消耗掉。现在 in 只包含一个标记 123。现在是这样。

while 循环文本表达式中的第一个条件是 in.hasNextInt() == false 已检查。它将评估为 false,因为 in 确实有一个 int 作为下一个标记。但是,in 仍将包含 23。根据 docs.oracle.com:

public boolean hasNextInt(int radix)

Returns true if the next token in this scanner's input can be interpreted as an int value in the specified radix using the nextInt() method. The scanner does not advance past any input.

现在控制传递到 while 循环文本表达式中的下一个条件。 in.nextInt()/1000000。这里一个 23 将被扫描为一个 int 并返回。所以你的条件将评估为真。 while 循环测试表达式中的下一个条件未被检查,因为您使用了短路逻辑运算符。这里是 link 有关短路逻辑运算符的详细信息。

https://www.geeksforgeeks.org/short-circuiting-in-java-with-examples/#:~:text=In%20Java%20logical%20operators%2C%20if,is%20known%20as%20Short%2Dcircuit.&text=If%20there%20is%20an%20expression,evaluated%20and%20false%20is%20returned.

您的程序控制现在将在 while 循环内传递。这里第一条语句是in.next()。但是,'in 中没有可用的标记。 所以它会停在那里等待用户输入。这解释了你的说法。

then it just stops there even if I have other print statements following after

更糟糕的是,in.next() 将接受任何有效输入。所以你甚至可以输入 abc 并且循环将继续。 这与你想要的相反

public String next()

Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.

这里有一个 link 有关扫描仪 class 的更多信息 java:

https://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html

您的程序中有更多潜在错误,我无法在此答案中分享,因为它太长了。但是,我将提供一个根据您的需要工作的代码:

do
{
    System.out.print("Please enter your ID without any spaces (7 digits): ");
    // division with two integers by a million, if you had less than 7 digits would give zero
    // division with two integers by ten million, if you had more than 7 digits would give you greater than zero
        
    if (in.hasNextInt()) number = in.nextInt();
    else in.next();
}
while (number/1000000 == 0 || number/10000000 > 0);

该程序由一个简单的 do-while 循环组成。循环中的第一条语句提示用户输入他的 UID(7 位数字)。 假设用户键入 23 并按下回车键。 然后将此输入存储在某处以供扫描仪对象使用 in。让我们称之为 space input buffer。现在它包括:

23\n

\n代表newline feed。在循环中,下一条语句是:

in.hasNextInt() number = in.nextInt();

if 条件为真,因为 输入缓冲区 确实有一个 int,即 23 存储在其中。 if 后面的语句从 输入缓冲区 中提取 23,跳过 \n 并将提取的数字存储在 number 中。然后控制传递到 do-while 的测试条件,因为数字没有通过给定的约束,循环再次开始。现在输入缓冲区包括:

它是空的。现在假设这次用户输入 abc 并按下回车键。 input buffer更新为:

abc\n

由于 input buffer 不包含 int,因此程序控制再次传递给 if condition,其计算结果为 false。我们必须从 input buffer 中删除 abc如果我们不这样做,那么 do-while loop 中对 if 条件的每次调用都将计算为 false 并且 number 仍然包含 23所以循环的最终 test condition 将始终是 true 导致 infinite loop.

这就是为什么 else 部分中的 in.next() 是必要的:

else in.next();

由于 if condition 为假,程序控制移动到 else 部分,调用 in.next()input buffer 中提取 abc,跳过 \n 并且不会将其存储在任何地方。 它清空任何非整数部分的input buffer

如果您不提供任何输入并继续按回车键,请注意此实现。此提示信息Please enter your ID without any spaces (7 digits): 将不会显示,因为您需要向扫描器提供至少一个字符(不包括分隔符)的输入。

即使有一个名为 input buffer 的 space。它的工作并不像我解释的那么简单。 这种方法在简单的程序中确实有效。但是,在复杂的程序中,应该采用更好的方法

当使用 nextInt()next() 时,扫描器 不会 跳过\n。认为他们在编写其他程序时这样做可能会导致不同的错误。我用它来简化我的解释。 请访问扫描仪link 我在上面提到扫描仪方法的精确工作。