【问题标题】:try/catch with InputMismatchException creates infinite loop带有 InputMismatchException 的 try/catch 创建无限循环
【发布时间】:2012-09-24 00:03:15
【问题描述】:

所以我正在构建一个从用户输入中获取整数的程序。我有一个似乎非常简单的 try/catch 块,如果用户没有输入 int,则应该重复该块,直到他们输入。这是代码的相关部分:

import java.util.InputMismatchException;
import java.util.Scanner;


public class Except {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        boolean bError = true;
        int n1 = 0, n2 = 0, nQuotient = 0;

        do {
            try {
                System.out.println("Enter first num: ");
                n1 = input.nextInt();
                System.out.println("Enter second num: ");
                n2 = input.nextInt();
                nQuotient = n1/n2;
                bError = false;
            } 
            catch (Exception e) {
                System.out.println("Error!");
            }
        } while (bError);

        System.out.printf("%d/%d = %d",n1,n2, nQuotient);
    }
}

如果我为第二个整数输入 0,那么 try/catch 会完全按照它应该做的那样做,并让我再次输入它。但是,如果我有一个 InputMismatchException,比如为其中一个数字输入 5.5,它只会在无限循环中显示我的错误消息。为什么会发生这种情况,我该怎么办? (顺便说一句,我已经尝试显式键入 InputMismatchException 作为要捕获的参数,但它并没有解决问题。

【问题讨论】:

    标签: java exception


    【解决方案1】:

    您需要在收到错误时致电next();。另外建议使用hasNextInt()

           catch (Exception e) {
                System.out.println("Error!");
               input.next();// Move to next other wise exception
            }
    

    在读取整数值之前,您需要确保扫描仪有一个。而且你不需要那样的异常处理。

        Scanner scanner = new Scanner(System.in);
        int n1 = 0, n2 = 0;
        boolean bError = true;
        while (bError) {
            if (scanner.hasNextInt())
                n1 = scanner.nextInt();
            else {
                scanner.next();
                continue;
            }
            if (scanner.hasNextInt())
                n2 = scanner.nextInt();
            else {
                scanner.next();
                continue;
            }
            bError = false;
        }
        System.out.println(n1);
        System.out.println(n2);
    

    Scanner的Javadoc

    当扫描器抛出 InputMismatchException 时,扫描器不会传递导致异常的令牌,以便可以通过其他方法检索或跳过它。

    【讨论】:

    • 这真的很棒,谢谢!您能否更详细地解释一下为什么需要next() 命令?我有一些想法,但对我来说有点不清楚。
    【解决方案2】:

    由于try block 中的bError = false 语句从未到达,并且该语句被输入所采用的,它不断打印错误在无限循环中

    通过hasNextInt()尝试以这种方式使用它

    catch (Exception e) {
                System.out.println("Error!");
               input.hasNextInt();         
            }
    

    或者尝试使用nextLine() 加上Integer.parseInt() 来获取输入......

    Scanner scan = new Scanner(System.in);
    
    int num1 = Integer.parseInt(scan.nextLine());
    int num2 = Integer.parseInt(scan.nextLine());
    

    【讨论】:

      【解决方案3】:

      补充 AmitD 的答案:

      只需复制/粘贴您的程序并获得以下输出:

      Error!
      Enter first num: 
      .... infinite times ....
      

      如你所见,指令:

      n1 = input.nextInt();
      

      输入双数时不断抛出异常,这是因为您的流未被清除。要修复它,请遵循 AmitD 的答案。

      【讨论】:

        【解决方案4】:

        @Limp,您的答案是正确的,只需在读取输入时使用 .nextLine() 即可。示例代码:

            do {
                try {
                    System.out.println("Enter first num: ");
                    n1 = Integer.parseInt(input.nextLine());
                    System.out.println("Enter second num: ");
                    n2 = Integer.parseInt(input.nextLine());
                    nQuotient = n1 / n2;
                    bError = false;
                } catch (Exception e) {
                    System.out.println("Error!");
                }
            } while (bError);
        
            System.out.printf("%d/%d = %d", n1, n2, nQuotient);
        

        在下面的链接中阅读有关导致此问题的原因的说明。查找我在此线程中发布的详细信息的答案。 Java Homework user input issue

        好的,我将简要介绍一下。当您使用 nextInt() 读取输入时,您只读取了数字部分,但 ENDLINE 字符仍在流中。这是主要原因。现在看看上面的代码,我所做的只是阅读整行并解析它,它仍然会抛出异常并按照您期望的方式工作。您的其余代码工作正常。

        【讨论】:

          【解决方案5】:

          你也可以试试下面的

             do {
                  try {
                      System.out.println("Enter first num: ");
                      n1 = Integer.parseInt(input.next());
          
                      System.out.println("Enter second num: ");
                      n2 = Integer.parseInt(input.next());
          
                      nQuotient = n1/n2;
          
                      bError = false;
                  } 
                  catch (Exception e) {
                      System.out.println("Error!");
                      input.reset();
                  }
              } while (bError);
          

          【讨论】:

            【解决方案6】:

            另一个选项是定义 Scanner input = new Scanner(System.in);在 try 块中,这将在您每次需要重新输入值时创建一个新对象。

            【讨论】:

              【解决方案7】:

              要遵循 debobroto das 的回答,您也可以放在

              之后
              input.reset();
              input.next(); 
              

              我有同样的问题,当我尝试这个时。它完全修复了它。

              【讨论】:

                猜你喜欢
                • 2021-12-18
                • 2018-01-16
                • 2016-03-21
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多