我是否必须更改我的代码以使用扫描仪才能使 inputmismatch 异常起作用?

问题描述

我的 InputMismatchException 不起作用,因为当我在输入中放入类似 double 的内容而不是异常输出消息时,它给了我:

Exception in thread "main" java.lang.NumberFormatException: For input string: "1.2"
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:652)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at reviewGUI.NChooseR.main(NChooseR.java:32)

我注意到很多其他 InputMismatchExceptions 使用扫描器而不是 DataInputStream,我是否必须将其更改为该格式才能使其工作?这是我的代码的一部分:

    public static void main(String[] args) throws IOException {
    DataInputStream input = new DataInputStream (system.in);
    
    int numChosenObj = -1;
    int numTotalObj=-1;
    
    
    try
    {
    System.out.print("Enter the number of objects to choose: ");
    numChosenObj = Integer.parseInt(input.readLine());
    }
    catch(InputMismatchException e)
    {
        System.out.println("You must input an integer value.");
        
    }
    
    try
    {
    System.out.print("Enter the total number of objects to choose from: ");
    numTotalObj = Integer.parseInt(input.readLine());
    }
    catch(InputMismatchException e)
    {
        System.out.println("You must input an integer value.");
        
    }
    
    int difference = numTotalObj-numChosenObj;
    
    int rFact = factorial(numChosenObj);
    int nFact = factorial(numTotalObj);
    int differenceFact = factorial(numTotalObj-numChosenObj);
    
    int totalWaystochoose = nFact/(rFact*differenceFact);
    System.out.println();
    System.out.println("There are " + totalWaystochoose + " ways to choose " + numChosenObj + " objects from " + numTotalObj + " total number of objects.");
    
    
    
}

解决方法

基本问题是 input.readLine() 不会抛出 InputMismatch,因为那里有一行,你不能没有(如果没有行,readLine() 方法只会等待直到存在,或者如果流关闭则返回 null)。 InputMismatch 仅在您要求某些特定数据类型时发生,例如“an int,please”。

Integer.parseInt,如果传入的字符串不是整数,将抛出 NumberFormatException 而不是 InputMismatchException。

直接的解决方法是捕获 NumberFormatException。但是你让这段代码变得比它需要的复杂得多。

Scanner s = new Scanner(System.in);
s.useDelimiter("\\R"); // the enter key delimits.

System.out.print("Enter the number of objects to choose: ");
numChosenObj = s.nextInt();

System.out.println("Enter your name: ");
name = s.next();

注意:永远不要调用scanner.nextLine。它是“坏的”(它按照 api 所说的去做,但不是你想的那样)。要读取一行,请调用 .next()。这是由于正确设置分隔符而起作用的。忘记 DataInputStream。

现在如果你想打印一些定制的东西,我会做一个方法:


public int askForInt(Scanner s,String prompt) {
  while (true) {
    try {
      System.out.print(prompt);
      return s.nextInt();
    } catch (InputMismatchException e) {
      System.out.println("An integer number is required.");
    }
  }
}

现在您可以调用 askForInt(s,"Enter the number of objects to choose: "),这会询问,并一直询问直到用户输入内容。

每当您有复制/粘贴代码的倾向时,您都应该始终思考:嗯,我正在复制的代码是否有明显的单一目的?如果答案是肯定的,请制定一个方法。

class App {
  public static void main(String[] args) throws Exception {
    new App().go(); // your main should always be a one-liner,really.
  }

  public void go() throws Exception {
    Scanner s = new Scanner(System.in);
    s.useDelimiter("\\R");
    
    int numChosenObj = askInt(s,"Enter the number of objects to choose: ");
    int numTotalObj = askInt(s,"Enter the total number of objects to choose from: ");
    
    int difference = numTotalObj-numChosenObj;
    
    int rFact = factorial(numChosenObj);
    int nFact = factorial(numTotalObj);
    int differenceFact = factorial(numTotalObj-numChosenObj);
    
    int totalWaysToChoose = nFact/(rFact*differenceFact);
    System.out.println();
    System.out.println("There are " + totalWaysToChoose + " ways to choose " + numChosenObj + " objects from " + numTotalObj + " total number of objects.");
  }

  private int askInt(Scanner s,String prompt) {
    while (true) {
      System.out.print(prompt);
      try {
        return s.nextInt();    
      } catch (InputMismatchException e) {
        System.out.println("An integer number is required.");
      }
    }
  }
} 

看起来干净多了,不是吗?