使用扫描仪从控制台读取号码的最佳方法是什么?

时间:2019-07-15 03:00:05

标签: java

我正在尝试编写一个函数来验证用户的输入。仅在用户输入双精度数字时返回。

private static double getDouble(String name) {
    double res = 0;
    Scanner s = new Scanner(System.in);
    while (true) {
        System.out.println("Please input " + name + ":");
        if (s.hasNextDouble()) {
            res = s.nextDouble();
            break;
        }
        else s.nextLine();
    }
    s.close();
    return res;
}

但是,它只能在第一次使用。如果我是在第一次之后第二次调用该函数,则nextLine()将引发异常。

double length = 0, width = 0;
length = getDouble("length of picture");
width = getDouble("width of picture");

请参阅Output Screenshot

有人可以告诉我我在这里犯了什么错误吗?以及如何解决/避免它?

谢谢。

2 个答案:

答案 0 :(得分:4)

我为获取用户输入做了另一种方式。只需参考代码和代码注释以了解详细信息。

private static double getDouble(String name) {
    double res = 0;
    Scanner s = new Scanner(System.in);
    while (true) {
        try {
            System.out.print("Please input " + name + ":");
            res = Double.parseDouble(s.nextLine()); // Just get the user input as a string then try to convert it into a double
            break; // if there is no error in the string to double conversion it means that the input is valid, thus break the loop
        } catch (Exception e) { // catch possible errors in case the input is invalid
            System.out.println("Your input is invalid!"); // print desired error message then the loop will execute again getting another user input
        }
    }
    s.close();
    return res;
}

编辑 这是因为在该方法之后您已经关闭了扫描仪实例。请参阅this,为什么不起作用。您也可以参考它。

如果要使用hasNextDouble,则可以将扫描程序作为参数传递给getDouble方法,也可以将扫描程序声明为类变量。两者都只会导致声明并关闭1个扫描仪。

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        double tmp = getDouble(s, "Tmp");
        double tmp2 = getDouble(s, "Tmp");
        s.close();
    }

    private static double getDouble(Scanner s, String name) {
        double res = 0;
        while (true) {
            System.out.println("Please input " + name + ":");
            if (s.hasNextDouble()) {
                res = s.nextDouble();
                break;
            } else
                s.nextLine();
        }
        return res;
    }

答案 1 :(得分:1)

关闭 System.in 的扫描仪对象(s.close();)之前,必须先重新启动应用程序,然后才能使用扫描仪。最好让Scanner对象保持打开状态,直到您完全确定不再需要它为止。

个人而言,我真的不喜欢故意依赖异常来处理无效情况,但在这种情况下,它非常适合:

private static double getDouble(String name) {
    double res = 0.0d;
    Scanner s = new Scanner(System.in);
    while (res == 0.0d) {
        System.out.print("Please input " + name + ": --> ");
        try {
            res = s.nextDouble(); 
        } 
        catch (Exception e) { 
            // If input is invalid
            System.out.println("Your input is invalid! Numerical Values Only!"); 
            /* Clear the scanner buffer otherwise the response 
               above will continue to display over and over 
               again.            */
            s.nextLine();   
            res = 0.0d;
        }
    }
    return res;
}

您也可以在不使用异常陷阱的情况下执行此操作:

private static double getDouble(String name) {
    String res = "";
    Scanner s = new Scanner(System.in);
    while (res.equals("")) {
        System.out.print("Please input " + name + ": ");
        res = s.nextLine();
        /* If the User supplies anything that is NOT a string 
           representation of a signed or unsigned integer or 
           double type numerical value. A regular Expression is 
           used here with the String#matches() method.       */
        if (!res.matches("-?\\d+(\\.\\d+)?")) {
            // Input is invalid...
            System.out.println("Your input is invalid (" + res + ")! Only Integer or Double Type Numerical Values Are Allowed!");
            res = "";
        }
    }
    return Double.parseDouble(res);
}