问题描述
我想在 input=scanner.nextInt
周围放置一个 try/catch 以在输入一个字母时抛出 InputMismatchException,我会不断陷入无限循环。这是带有无限循环的代码。解决此问题的最佳方法是什么?
public void setNumberOfPlayers(Scanner scanner) {
boolean valid = false;
this.numberOfPlayers = 0;
int input = 0;
do {
do {
System.out.println("Please enter the number of players (minimum " + MIN_PLAYERS + " & maximum "
+ MAX_PLAYERS + ".)");
try {
input = scanner.nextInt();
}catch (InputMismatchException e ) {
System.out.println("Please type a numeric digit only");
}
// this.numberOfPlayers = scanner.nextInt();
if (input > MAX_PLAYERS || input < MIN_PLAYERS) {
System.out.println("Invalid input. Enter the number of players");
valid = false;
} else {
this.numberOfPlayers = input;
valid = true;
}
} while (input > MAX_PLAYERS || input < MIN_PLAYERS);
System.out.printf("You have chosen to include %d players. is this correct? (Y/N)",this.numberOfPlayers);
String answer = scanner.next();
switch (answer) {
case "y":
case "Y":
System.out.println("Great - lets start the game with " + this.numberOfPlayers + " players");
valid = true;
break;
case "n":
case "N":
System.out.println("Please re-enter the number of players");
// this.numberOfPlayers = scanner.nextInt();
valid = false;
break;
default:
System.out.println("Please enter a valid response - y / n");
valid = false;
break;
}
} while (!valid);
}
解决方法
我认为这种方法存在多个问题,如果您设置了一个有效的数字,但在第二次检查中没有确认,那么您将再次进行第一次检查,输入无效字符不会再次询问您,因为输入上次设置正确。所以我会说你想将“重置”状态移动到循环中:
boolean valid;
int input;
do {
valid = false;
this.numberOfPlayers = 0;
input = 0;
do {
可以在您的扫描仪上检查 'hasNext()' 以便您知道那里有东西。 而不是检查异常,你可以测试'hasNextInt()'
if (scanner.hasNextInt()) {
System.out.println("Read a int" + scanner.nextInt());
}
但总的来说,我认为它不会继续读取,如果未读取 int,我认为扫描仪中的指针/索引不会在进行中,因为它不知道那里有什么以及需要进行多少字节不破坏接下来的多头,浮点数或任何将在那里的东西(它无法提前知道)。你可能给它一个新的输入,但阅读器仍然没有有效地处理前一个,所以它没有进展。
所以我会说更好的是读取一行“nextLine()”并确保它无论如何都被正确读取,然后尝试将字符串转换为int,然后确定输入是否是您的想要。
我看到的其他问题是输入和有效标志有一些重叠的功能,条件测试多次输入的有效范围(在 if 条件和 while 条件内,重复代码将导致错误)。也许 while 条件可以改为检查有效标志:
变化:
while (input > MAX_PLAYERS || input < MIN_PLAYERS);
为此:
while (!valid);
而且我不确定 this.numberOfPlayers = 0;
是否也很好,setNumberOfPlayers 暗示您将其设置为有效值,那么为什么您在此期间重置,当两个循环完成时然后设置将其设置为下一个新的有效值,同时不要将其重置为无效值。我想这不是多线程的大问题,但仍然感觉不对。