扫描仪上的其他条件混乱 class

Else condition confusion on Scanner class

请检查 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.hasNextInt();,您输入 d 并按下回车键(即循环的第 4 次迭代)。此时扫描仪的内部状态可以像这样可视化:

3 \n d \n
 ^

\n 表示换行符,^ 表示扫描器当前正在扫描的位置。最后一次调用 nextInt 消耗了 3,但没有消耗掉它后面的新行,这导致扫描器位于它现在所在的位置。

现在,扫描下一个令牌 d(但未消耗!)。它不是 int,所以 hasNextInt returns false。您的 else 块被执行。打印错误消息。 nextLine 消耗所有内容,直到下一个换行符,包括换行符,它将指针移动到:

3 \n d \n
    ^

现在我们处于循环的下一次迭代,下一个标记仍然是d,所以同样的事情再次发生。您的 else 块,运行,错误消息打印,nextLine 消耗,指针移动:

3 \n d \n
         ^

将此与 nextLineelse 之外的情况进行比较。这意味着每次 hasNextInt 被调用时,指针总是在 \n 之后。指针将始终从上一次循环迭代中的 nextLine 移动到 \n 之后。换句话说,循环的每次迭代,你总是在数字之后消耗新行。