请检查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();
}
}
构成此问题的三件事:
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
^
与nextLine
在else
外部的情况进行比较。这意味着每次调用hasNextInt
时,指针将始终位于\n
之后。指针将始终从循环的上一迭代的\n
移到nextLine
之后。换句话说,循环的每次迭代,您总是在数字之后使用新行。