Scanner类的其他条件混乱

问题描述 投票:0回答:1

请检查else条件的sc.nextLine(),这里我给出10个数字,然后求和。如果提供任何无效数据(不是int),它将进入else条件。考虑输入为-1个23d然后它两次显示无效数据行。如果我将sc.nextLine()放在else之外,则可以正常工作。我想知道两次打印的逻辑。

import 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();
    }

}
java java.util.scanner
1个回答
1
投票

构成此问题的三件事:

  • [nextInt仅消耗组成下一个整数的字符,并且仅此而已。
  • nextLine一直消耗字符,直到到达下一个新的行字符。它还占用换行符
  • hasNextInt默认将换行符当作定界符。

假设代码已经运行到boolean isInt = sc.hasNextInt();行,您输入了d并按Enter键(即循环的第4次迭代)。此时,扫描仪的内部状态可以像这样可视化:

3 \n d \n
 ^

\n表示换行符,^表示扫描仪当前正在扫描的位置。对nextInt的最后一次调用消耗了3,但没有占用其后的新行,这使扫描仪位于现在的位置。

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

3 \n d \n
    ^

现在我们处于循环的下一个迭代中,下一个标记仍为d,因此同样的事情再次发生。您的else块运行,出现错误消息,nextLine被消耗,并且指针被移动:

3 \n d \n
         ^

nextLineelse外部的情况进行比较。这意味着每次调用hasNextInt时,指针将始终位于\n之后。指针将始终从循环的上一迭代的\n移到nextLine之后。换句话说,循环的每次迭代,您总是在数字之后使用新行。

© www.soinside.com 2019 - 2024. All rights reserved.