扫描器nextInt()导致循环内无休止的错误

时间:2019-01-22 09:29:22

标签: java java.util.scanner

以下代码在用户未输入数字时输出无尽错误。

Scanner scn = new Scanner(System.in);
System.out.println("Enter the number: ");   
int n = 0;  
while(true){
    try {
        n = scn.nextInt();
    } catch (Exception e) {
        e.printStackTrace();
        continue;
    }
    break;
}

我希望代码在用户输入非数字时等待新输入。

5 个答案:

答案 0 :(得分:12)

在javadoc中,

  

扫描程序引发InputMismatchException时,扫描程序将不会   传递导致异常的令牌,以便可以将其检索   或通过其他方法跳过。

对于您来说,scn.nextInt()必须抛出InputMismatchException。但是令牌没有传递(换句话说,输入令牌挂在那里,由Scanner传递)。因此,在循环的下一次迭代中,scn.nextInt()会再次读取同一令牌,并再次引发异常,从而导致无限循环。

如果您检查Scanner对象内部的CharBuffer(HeapCharBuffer?)值,它仍然包含您第一次输入并导致此问题的输入。另外,您不能明确清除扫描仪的缓冲区。

此外,当心资源泄漏!

答案 1 :(得分:3)

我不使用nextInt,而是将输入读取为字符串,然后尝试将其转换

Scanner scn = new Scanner(System.in);
System.out.println("Enter the number: ");   
int n = 0;  
while(true) {
    String input = scn.nextLine();

    try {
        n = Integer.valueOf(input);
        break;
    } catch (Exception e) {
        System.out.println( input + " is not a valid number. Try again.");
    }
}
System.out.println("You entered " + n);

答案 2 :(得分:1)

我的版本:

public class IsNumber {
    public static void main(String o[]) {
        Scanner scn = new Scanner(System.in);
        System.out.println("Enter the number: ");   
        String str = null;
        do{
            str = scn.next();
            if(isInteger(str))
                break;
        }while(true);

        System.out.println("Number Entered: " + Integer.parseInt(str));
        scn.close();
    }

    private static boolean isInteger(String s) {
        try { 
            Integer.parseInt(s); 
        } catch(Exception e) { 
            return false; 
            }
        return true;
    }
}

答案 3 :(得分:1)

在代码示例中,您在continue块内catch {}。这将再次运行循环,因为您可以无限期地运行循环。在循环中,与以前一样验证了相同的输入,因为扫描程序将再次使用相同的输入,因此它将再次引发异常。

这基本上是发生的:

  1. 扫描仪未接收到整数。
  2. 引发异常。
  3. 遇到继续。
  4. 检查循环条件,这是正确的,因此循环再次运行。
  5. 返回步骤1。

您可以将输入作为字符串检索,然后验证它实际上是数字。

答案 4 :(得分:0)

快速修复

try {
    n = scn.nextInt();
} catch(Exception e) {
    e.printStackTrace();
    scn.nextLine(); // <-- add this to move to the next line
    continue;
}