如何使用Scanner处理由无效输入(InputMismatchException)引起的无限循环

所以,我对这段代码感到困惑:

import java.util.InputMismatchException; import java.util.Scanner; public class ConsoleReader { Scanner reader; public ConsoleReader() { reader = new Scanner(System.in); //reader.useDelimiter(System.getProperty("line.separator")); } public int readInt(String msg) { int num = 0; boolean loop = true; while (loop) { try { System.out.println(msg); num = reader.nextInt(); loop = false; } catch (InputMismatchException e) { System.out.println("Invalid value!"); } } return num; } } 

这是我的输出:

插入整数:
无效值!
插入整数:
无效值!

根据扫描仪的javadoc :

当扫描程序抛出InputMismatchException时,扫描程序将不会传递导致exception的标记,因此可以通过其他方法检索或跳过它。

这意味着如果下一个标记不是int ,它会抛出InputMismatchException ,但令牌仍然存在。 因此,在循环的下一次迭代中, reader.nextInt()再次读取相同的标记并再次抛出exception。 你需要的是用它。 在catch添加reader.next()以使用令牌,该令牌无效且需要被丢弃。

 ... } catch (InputMismatchException e) { System.out.println("Invalid value!"); reader.next(); // this consumes the invalid token } 

我要做的是使用Scanner.nextLine()读取整行。 然后创建另一个读取返回字符串的扫描程序。

 String line = reader.nextLine(); Scanner sc = new Scanner(line); 

这将使您的示例函数如下所示:

  public int readInt(String msg) { int num = 0; boolean loop = true; while (loop) { try { System.out.println(msg); String line = reader.nextLine(); Scanner sc = new Scanner(line); num = sc.nextInt(); loop = false; } catch (InputMismatchException e) { System.out.println("Invalid value!"); } } return num; } 

通过这种方式,您可以使用一个获取输入的扫描仪和一个可以validation输入的扫描仪,这样您就不必担心如果输入正确的输入forms的读者关怀。

你的while-do的守卫是’循环’变量。

在代码到达赋值循环= false之前抛出的exception本身; 确切地说,在以前的语句中抛出exception,即num = reader.nextInt();

抛出exception时,’loop’变量的值为’true’,但是你的代码跳转到catch块然后重复while-do。 这个while-do永远不会停止,因为下一次迭代会再次抛出exception,再次跳转到catch块等等。

要在做什么时终止这个,你需要用另一个合乎逻辑的东西保护你的做法,例如:

  1. 当读者获得非int字符时退出
  2. EOF时退出

这可以在catch块或其他一些行中完成。 但精确的解决方案取决于您的规格。

你也可以试试这个:

  public int readInt(String msg) { int num = 0; try { System.out.println(msg); num = (new Scanner(System.in)).nextInt(); } catch (InputMismatchException e) { System.out.println("Invalid value!"); num = readInt(msg); } return num; } 
 package nzt.nazakthul.app; import java.util.*; public class NztMainApp { public static void main(String[] args) { ReadNumber readObj = new ReadNumber(); readObj.readNumber(); } } class ReadNumber { int no; int readNumber() { Scanner number = new Scanner(System.in); int no=0; boolean b=true; do { try { System.out.print("Enter a number:\t"); no = number.nextInt(); } catch (InputMismatchException e) { System.out.println("No Number"); //e.printStackTrace(); b=false; } } while (b); return no; } } 

我个人使用BufferedReader和InputStreamReader来读取String并检查是否是数字,但扫描器代码较少。 检查代码并运行正常。