Java 扫描器类上的Else条件混淆

Java 扫描器类上的Else条件混淆,java,java.util.scanner,Java,Java.util.scanner,请检查else条件的sc.nextLine(),这里我给出10个数字,然后得到它们的总和。如果提供了任何无效数据(不是int),它将转到else条件。 考虑输入为: 1. 2. 3. D 然后,它将两次显示无效数据行。如果我把sc.nextLine()放在else之外,它就可以正常工作。 我想知道两次印刷背后的逻辑 导入java.util.Scanner public class Main { public static void main(String[] args) {

请检查else条件的sc.nextLine(),这里我给出10个数字,然后得到它们的总和。如果提供了任何无效数据(不是int),它将转到else条件。 考虑输入为: 1. 2. 3. D 然后,它将两次显示无效数据行。如果我把sc.nextLine()放在else之外,它就可以正常工作。 我想知道两次印刷背后的逻辑

导入java.util.Scanner

public class Main {
    public static void main(String[] args) {
        int count = 0;
        int sum = 0;
        Scanner sc = new Scanner(System.in);


        while (true) {

            System.out.print("Enter number " + (count + 1) + " - ");
            boolean isInt = sc.hasNextInt();
            if (isInt) {
                int num = sc.nextInt();
                sum += num;
                count++;
                if (count == 10) {
                    break;
                }
            } else {
                System.out.print("Invalid number, put int");

                sc.nextLine();

            }

            //  sc.nextLine();
        }

        System.out.println(sum);
        sc.close();
    }

}

这个问题有三个方面:

  • nextInt
    仅使用构成下一个整数的字符,并且不会超出该范围
  • nextLine
    一直使用字符,直到到达下一个新行字符。它还使用新行字符
  • hasNextInt
    默认情况下将新行视为分隔符
假设代码已运行到行
boolean isInt=sc.hasnetint()
输入
d
并按enter键(即循环的第四次迭代)。此时,扫描仪的内部状态可视为:

3 \n d \n
 ^
\n
表示新行字符,
^
表示扫描仪当前扫描的位置。最后一次调用
nextInt
消耗了
3
,但没有消耗它后面的新行,这导致扫描仪处于当前位置

现在,下一个令牌,
d
,将被扫描(但不会被消耗!)。它不是int,因此
hasNextInt
返回false。执行
else
块。将打印错误消息
nextLine
将使用所有内容,直到下一个新行字符,包括新行字符,它将指针移动到:

3 \n d \n
    ^
现在我们在循环的下一次迭代中,下一个标记仍然是
d
,因此同样的事情再次发生。您的
else
阻塞、运行、错误消息打印、
nextLine
消耗,指针移动:

3 \n d \n
         ^


将此与
nextLine
else
之外的情况进行比较。这意味着每次调用
hasNextInt
,指针将始终位于
\n
之后。指针将始终通过循环上一次迭代的下一行移动到
\n
之后。换句话说,在循环的每次迭代中,您总是使用数字后面的新行。

为什么不使用nextInt?您也会得到一个例外。您需要检查是否到达流的末尾,或者我只需在else部分添加一个
中断
,如果发现无效数据,则结束循环。您没有清除旧的无效输入,因此它仍然可以为您读取。sc.nextLine()甚至用户在此处输入输入。在你继续撤退之前先消耗掉它。你还没有退出循环。相关:@Ackdari-exception?什么样的例外?在无效输入的情况下,计数不会增加,直到用户以int给出输入,它将继续询问输入。