提问人:mateusmaso 提问时间:8/26/2010 最后编辑:gparyanimateusmaso 更新时间:4/19/2019 访问量:44536
如何使用 Scanner 处理由无效输入 (InputMismatchException) 引起的无限循环
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
问:
所以,我被这段代码卡住了:
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;
}
}
这是我的输出:
插入整数:
值无效!
插入整数:
值无效!
。
答:
根据 Scanner 的 javadoc:
当扫描仪抛出 InputMismatchException,扫描程序 不会传递导致的令牌 例外,因此可能是 通过其他一些检索或跳过 方法。
这意味着,如果下一个标记不是 ,它会抛出 ,但令牌会留在那里。因此,在循环的下一次迭代中,再次读取相同的令牌并再次引发异常。你需要的是用完它。在 ur 内部添加一个用于消耗的令牌,该令牌无效,需要丢弃。int
InputMismatchException
reader.nextInt()
reader.next()
catch
...
} catch (InputMismatchException e) {
System.out.println("Invalid value!");
reader.next(); // this consumes the invalid token
}
评论
nextLine()
next()
this has spaces in it
我要做的是使用 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;
}
这样一来,您就有一台扫描仪来获取输入,另一台扫描仪可以验证输入,因此您不必担心读者是否输入了正确的输入形式。
while-do 的守卫是 'loop' 变量。
在代码到达赋值之前抛出的异常本身 循环 = false; 准确地说,异常是在上一个语句中抛出的,即 num = reader.nextInt();
抛出异常时,“loop”变量的值为“true”,但您的代码会跳转到 catch 块,然后重复 while-do。这个 while-do 永远不会停止,因为下一次迭代会再次抛出异常,再次跳转到 catch 块,依此类推。
要终止此 while-do,您需要用另一个合乎逻辑的东西来保护您的 while-do,例如:
- 当读取器获得非整数字符时退出
- 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 并检查是否是数字,但使用 scanner 的代码更少。代码已检查并正常运行。
评论
while (true) { try { ....; return reader.nextInt(); } catch {....} }