如何使用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块等等。
要在做什么时终止这个,你需要用另一个合乎逻辑的东西保护你的做法,例如:
- 当读者获得非int字符时退出
- 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并检查是否是数字,但扫描器代码较少。 检查代码并运行正常。