Java 扫描器类上的Else条件混淆
请检查else条件的sc.nextLine(),这里我给出10个数字,然后得到它们的总和。如果提供了任何无效数据(不是int),它将转到else条件。 考虑输入为: 1. 2. 3. D 然后,它将两次显示无效数据行。如果我把sc.nextLine()放在else之外,它就可以正常工作。 我想知道两次印刷背后的逻辑 导入java.util.ScannerJava 扫描器类上的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) {
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给出输入,它将继续询问输入。