为什么扫描器不在 try-catch while 循环中请求其他输入 java

Why doesn't scanner ask for an other input in a try-catch while loop java

假设我需要继续询问用户,直到他输入 double

我所做的是使用 while 循环并检查是否有异常。

如果有异常,我会去要求下一次输入

double bal = 0;
Scanner sc = new Scanner(System.in);
while (true) {
    try {
        System.out.println("Enter the balance");
        bal = sc.nextDouble();
        break;
        } catch (Exception e) {
          System.out.println("That isn't a number");
    }
}
System.out.println("Bal is " + bal);
sc.close();

但是,如果我输入一个非双精度值,那么它不会要求下一个输入,而是继续打印以无限循环结尾的那两行。

Enter the balance
XYZ
That isn't a number
Enter the balance
That isn't a number
Enter the balance
That isn't a number
Enter the balance
That isn't a number
....

我缺少什么?

您需要通过在 catch 块中调用 sc.next() 来丢弃流中的先前输入。遗憾的是,当输入失败时,扫描仪不会自动执行此操作。

使用sc.next()丢弃错误输入:

while (true) {
    try {
        System.out.println("Enter the balance");
        bal = sc.nextDouble();
        break;
    } catch (InputMismatchException e) {
        System.out.println("That isn't a number");
        sc.next();
    }
}

我还建议捕获特定异常(在本例中为 InputMismatchException)。这样,如果出现其他问题(例如,标准输入流已关闭),您将不会错误地打印 "That isn't a number"

来自 nextDouble 文档:

If the translation is successful, the scanner advances past the input that matched.

所以当输入不匹配时,扫描器不会前进。因此,当您执行下一次迭代时 nextDouble 输入尚未清除,它仍会读取相同的输入。

您应该在失败时通过读取 next() 来推进输入,或者将输入读取为字符串并尝试解析结果,这样即使值是非法的,输入也已被清除并下一步迭代你可以读取一个新值/输入:

public static void main(String[] args) {
    double bal = 0;
    Scanner sc = new Scanner(System.in);
    while (true) {
        try {
            System.out.println("Enter the balance");
            bal = Double.parseDouble(sc.next());
            break;
            } catch (Exception e) {
              System.out.println("That isn't a number");
        }
    }
    System.out.println("Bal is " + bal);
    sc.close();
}