提问人:eric_codes 提问时间:10/26/2023 最后编辑:eric_codes 更新时间:11/4/2023 访问量:115
为什么我的 while(Scanner.hasNext()) 循环永远不会退出?
Why does my while(Scanner.hasNext()) loop never exit?
问:
我正在学习 Java 并构建一个战舰游戏作为学习练习。我创建了一个方法来接收来自用户的一组坐标,该坐标以两个整数的形式输入,并用空格分隔。我已经验证了两个整数是否被正确读取,但随后程序继续从键盘接收输入,并且永远不会退出 while 循环。因此,该方法从不返回一组坐标。我已经搜索并阅读了很多关于使用 Scanner 的信息,但我看不出我的代码有什么问题。你能告诉我我做错了什么吗?
传入的扫描程序是 。Scanner(System.in)
public static int[] getCoordinates(Scanner input, String prompt) {
int[] coordinates = new int[2];
boolean invalid = false;
do {
System.out.println(prompt + ":");
int index = 0;
while (input.hasNext()) {
if (input.hasNextInt() && index < 2) {
coordinates[index] = input.nextInt();
index++;
} else {
input.next();
}
}
if (coordinates[0] < 0 || coordinates[0] > 4 || coordinates[1] < 0 || coordinates[1] > 4) {
System.out.println("Invalid coordinates. Choose different coordinates.");
invalid = true;
}
} while (invalid);
return coordinates;
}
我希望用户输入两个整数,然后按回车键,循环将退出并继续执行该方法的其余部分。while(input.hasNext())
更新:我通过简单地执行以下操作来获得基本功能。我不确定这是否可靠,但现在可以。
int index = 0;
while (index < 2) {
if (input.hasNextInt()) {
coordinates[index] = input.nextInt();
index++;
}
}
这也很好用。感谢@k314159!
String[] answer = input.nextLine().split(" ");
if (answer.length >= 2) {
coordinates[0] = Integer.parseInt(answer[0]);
coordinates[1] = Integer.parseInt(answer[1]);
}
答:
原始循环永远不会退出的原因是因为它等待输入流 () 被关闭,这通常发生在程序终止时。它不会仅仅因为用户按 Enter 键而退出。while (input.hasNext())
System.in
如果要继续使用 while (input.hasNext())
循环,并且仍然允许用户输入后跟 Enter 的值,则可以像这样修改代码:
public static int[] getCoordinates(Scanner input, String prompt) {
int[] coordinates = new int[2];
boolean invalid = false;
do {
System.out.println(prompt + ":");
int index = 0;
while (index < 2) {
if (input.hasNextInt()) {
coordinates[index] = input.nextInt();
index++;
} else {
input.next(); // Consume the non-integer token
}
}
if (coordinates[0] < 0 || coordinates[0] > 4 || coordinates[1] < 0 || coordinates[1] > 4) {
System.out.println("Invalid coordinates. Choose different coordinates.");
invalid = true;
} else {
invalid = false;
}
} while (invalid);
return coordinates;
}
评论
while(input.hasNext())
“为什么我的while(Scanner.hasNext())循环永远不会退出?..."
它正在等待更多的输入。
在 Java 中,这有时被称为“阻塞”。
"...我希望用户输入两个整数,然后按回车键,
while(input.hasNext())
循环将退出并继续执行该方法的其余部分。..."
只需调用 nextInt 方法两次即可。
int[] coordinates;
boolean invalid;
do {
System.out.println(prompt + ":");
coordinates = new int[] { input.nextInt(), input.nextInt() };
invalid = false;
if (coordinates[0] < 0 || coordinates[0] > 4 || coordinates[1] < 0 || coordinates[1] > 4) {
System.out.println("Invalid coordinates. Choose different coordinates.");
invalid = true;
}
} while (invalid);
return coordinates;
更好的方法是在将值添加到坐标时检查值。
int[] coordinates = new int[2];
boolean invalid = true;
do {
System.out.println(prompt + ":");
switch (coordinates[0] = input.nextInt()) {
case 1, 2, 3, 4 -> {
switch (coordinates[1] = input.nextInt()) {
case 1, 2, 3, 4 -> invalid = false;
}
}
}
if (invalid) {
System.out.println("Invalid coordinates. Choose different coordinates.");
input.nextLine();
}
} while (invalid);
return coordinates;
或者,最好使用 Scanner#next 或 nextLine 方法以及 Integer#parseInt 方法计算输入。
int a = 0, b = 0;
boolean exit = false;
do {
System.out.println(prompt + ":");
try {
a = Integer.parseInt(input.next());
b = Integer.parseInt(input.next());
if (Math.min(a, b) < 0 || Math.max(a, b) > 4) throw new Exception();
exit = true;
} catch (Exception e) {
System.out.println("Invalid coordinates. Choose different coordinates.");
input.nextLine();
}
} while (!exit);
return new int[] { a, b };
或者,流。
int[] coordinates = null;
boolean exit = false;
do {
System.out.println(prompt + ":");
try {
coordinates
= input.tokens()
.limit(2)
.mapToInt(Integer::parseInt)
.peek(x -> {
if (x < 0 || x > 4)
throw new RuntimeException(); })
.toArray();
exit = true;
} catch (RuntimeException e) {
System.out.println("Invalid coordinates. Choose different coordinates.");
input.nextLine();
}
} while (!exit);
return coordinates;
评论
Scanner
System.in
input.nextLine()
line.split()
input.nextLine();