gpt4 book ai didi

java - 处理 InputMismatchException 时文本菜单中出现无限循环

转载 作者:行者123 更新时间:2023-12-01 09:18:43 26 4
gpt4 key购买 nike

我有一个家庭作业,要创建一个带有循环菜单的类来管理汽车队列。我们在上节课中学习了队列。

我的菜单工作得很好,直到捕获InputMismatchExceptionQueueEmptyException,之后它进入无限循环,甚至不会在userInput.nextInt()处停止;。当它捕获 QueueFullException 时,它会起作用,但其他的则不起作用。

我的代码是:

import java.util.*;

public class CarQueueManagement {

public static void main(String[] args) throws InputMismatchException, QueueFullException{
ArrayQueue queue = new ArrayQueue(3);;
Scanner userInput = new Scanner(System.in);
int carNum;
int choice = 0;

queue.add(1);

OUTER:
while (true) {
try{
System.out.println("ΜΕΝΟΥ:\n\t1. Άφιξη αυτοκινήτου");
System.out.println("\t2. Αναχώρηση αυτοκινήτου\n\t3. Κατάσταση ουράς\n\t4. Έξοδος");
System.out.print("\n\tΕπιλογή (1-4): ");
choice = userInput.nextInt();

switch (choice){
case 1:
System.out.print("\n\tΆφιξη αυτοκινήτου:\n\t\tΑριθμός Αμαξιού");
carNum = userInput.nextInt();
queue.add(carNum);
break;
case 2:
if(queue.isEmpty()){
System.out.println("\n\tΗ ουρά είναι άδεια, δεν χριάζεται διαγραφή.\n\n");
break;
}
String answer;
while(true){
System.out.print("\n\tΑναχώρηση αυτοκινήτου\n\t\tΕπιβεβαίωση; (y/n): ");
answer = userInput.next();
if(answer.equals("y")){
queue.remove();
break;
}
else if(answer.equals("n"))
break;
}
break;
case 3:
System.out.println("\n\tΚατάσταση ουράς:");
if(queue.isEmpty()) System.out.println("\t\tΗ ουρά είναι άδεια.\n\n");
else if(queue.isFull()) System.out.println("\t\tΗ ουρά είναι γεμάτη.\n\n");
else System.out.println("\t\tΗ ουρά έχει άδιες θέσοις.\n\n");
break;
case 4:
System.out.print("\n\nΕξοδος");
break OUTER;
default:
break;
}
}catch (InputMismatchException exc){
System.out.println("\t\tΛΑΘΟΣ ΕΙΣΑΓΩΓΗ\n");
}catch(QueueEmptyException exc){
System.out.println("\t\t" + exc.getMessage() + "\n");
}catch(QueueFullException exc){
System.out.println("\t\t" + exc.getMessage() + "\n");
}
}
}
}

最佳答案

摘自 java.util.Scanner docs 的介绍部分(强调我的):

When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.

如果没有详细信息,您的 while(true) 循环是:

while (true) {
try{
choice = userInput.nextInt();
switch (choice){
case 1:
...
}
} catch (InputMismatchException exc){
// Do nothing.
}
}

当用户输入无法转换为整数的内容时,Scanner 会抛出 InputMismatchException,您可以捕获并忽略该异常。然后 while 循环返回顶部,尝试执行 userInput.nextInt()...但 Scanner 仍在寻找相同的无效输入,因此它立即抛出另一个 InputMismatchException,您再次捕获并忽略该异常。执行在 while 循环的顶部继续,并再次调用 nextInt()...并且循环将永远持续下去。

您必须强制 Scanner 跳过错误的输入,因此您的 catch block 应如下所示:

}catch (InputMismatchException exc){
System.out.println("\t\t[chastise the user in Greek]\n");
userInput.next(); // Skip invalid input.
}

其他建议

作为一般规则,许多小方法比一个大方法更容易理解。嵌套的 while 循环和 switch 语句尤其难以理解。我只能通过将巨大的 main 方法分解为许多较小的私有(private)静态方法来找到该错误。

至少,每个菜单项都可以用自己的方法来处理。我还通过将整个菜单放入一个单独的方法中来摆脱 break 标签,该方法返回一个 boolean 指示用户是否完成。这将 main 内的整个循环减少为:

boolean done = false;
while (! done) {
try{
done = handleUserInput(queue, userInput);
} catch (InputMismatchException exc) {
System.out.println("\nINPUT ERROR\n");
userInput.next();
} // Other catch blocks as before...
}

我的handleUserInput没有做太多事情——它获取用户输入,确定哪个方法应该处理该输入,然后返回truefalse...它也可以变得比这更简单。

private static boolean handleUserInput(
final ArrayQueue queue,
final Scanner userInput
) {
boolean done = false;
printMenu();
int choice = userInput.nextInt();
switch (choice) {
case 1:
addToQueue(queue, userInput);
break;
case 2:
removeFromQueue(queue, userInput);
break;
case 3:
displayQueue(queue);
break;
case 4:
printExitMessage();
done = true;
break;
default:
break;
}
return done;
}

将各种菜单 Activity 拆分为单独的方法使它们更易于遵循。例如,当逻辑在 main 中混合在一起时,很难判断像 carNumanswer 这样的变量是否是问题的一部分。在此版本中,carNum 是捕获在 addToQueue 方法内的局部变量,因此当我在其他地方工作时,我可以完全忽略它。

关于java - 处理 InputMismatchException 时文本菜单中出现无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40318776/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com