3

在我的验证方法中,如果用户输入字母而不是十进制值,我希望它打印一条错误消息,该方法确实会在控制台上打印一条错误消息,但它会打印两次,例如如果我输入“dfdff”它打印出的不是小数点:
“错误,无效数字。再试一次”

“错误,无效号码。再试一次”

每次用户输入错误的值时,如何让它打印一次错误消息???

 public static double getVaildSubtotal(Scanner sc)
{

    double subtotal = 0.0;
    boolean isValid = false;
    while (isValid == false)
    {
       if (sc.hasNextDouble())
       {
           subtotal = sc.nextDouble();
           isValid = true;
       }
       else
       {
           System.out.println("Error! Invalid decimal value. Try again.");
       }
       sc.nextLine();

       if (isValid == true && subtotal <= 0)
       {
           System.out.println("Error! Number must be greater then 0.");
           isValid = false;
       }
       else if (isValid == true && subtotal >= 10000)
       {
          System.out.println("Error! Number must be less then 10000.");
           isValid = false; 
       }

    }

    return subtotal;
}
4

3 回答 3

2

现在我刚开始使用 Java,所以请对我温柔一点。

在我为课堂编写的一个小程序中,我遇到了类似的情况,所以我调整了这些原则:

public static double getVaildSubtotal(Scanner sc)
{ 
    double subtotal = 0.0;
    boolean isValid = false;
    while (isValid != true)
    {
        String stSubTotal = sc.nextLine().trim();
        int subTotalLength = stSubTotal.length();  
        boolean checkDouble = true;
        for (int k = 0; k < subTotalLength; k++)
        {
            if (Character.isDigit(stSubTotal.charAt(k)) != true)
            {
                System.out.println("Error! Invalid decimal value. Try again.");
                checkDouble = false;
            }
        }
        if (checkDouble == true)
        {
            subtotal = Double.parseDouble(stSubTotal);
            if (subtotal <= 0)
            {
                System.out.println("Error! Number must be greater then 0.");                    
            }
            else if (subtotal >= 10000)
            {
                System.out.println("Error! Number must be less then 10000.");                    
            }
            else
            {
                isValid = true;
            }
        }            
    }
    return subtotal;
}

无论如何,像这样,每个条目只会得到一个错误代码,因为条目会吞噬整行。

但是,如果您对重建轮子不感兴趣(老实说,我不会受到侮辱),代码的当前问题是您的 sc.nextLine(); 现在,.nextLine()

“将扫描仪推进到当前行并返回被跳过的输入。”

在这种情况下,这只是我的信念,你的 sc.nextLine(); 正在读取 .nextLine() 的输入,就像它应该的那样。所以当它来看看里面是否有双重时,不,没有双重,只有\n。

我建议删除 sc.nextLine(); 如果确实需要一个空格,希望它是一个 nextLine(),我会为 .nextLine() 添加另一个本地扫描仪;在验证方法中。

于 2013-02-13T07:34:20.310 回答
1

这可能是因为Scanner该类的nextDouble()方法不会“吃掉”换行符。这可能会导致该方法在通过和类似方法nextLine()读入原语之后移动到下一行之前返回一个空行。nextDouble()

这可能会导致一些棘手的结果,但最简单的方法是Scanner通过在此处添加额外的插入来强制显式处理换行符nextLine()

if (sc.hasNextDouble()) {
    subtotal = sc.nextDouble();
    sc.nextLine();
    isValid = true;
}

请注意,当扫描仪的分隔符不只是匹配换行符时,这可能会导致意外结果。在这种情况下,您可能会不小心跳过多个输入。由于您通常希望用换行符分割,无论如何,您可以通过在创建扫描仪时更改扫描仪的分隔符来创建更永久的解决方案,如下所示:

Scanner sc = new Scanner(System.in);
sc.useDelimiter("[\r\n]+");

使用该解决方案,您将不再需要使用额外的nextLine()调用,因为任何额外的换行符都将被忽略。但是,该系统也将无法响应空白行输入,该分隔符将被简单地跳过。如果您希望处理这些,您可以使用额外的nextLine()修复以及此分隔符以确保安全:

sc.useDelimiter("\r\n|[\r\n]");
于 2013-02-13T05:37:57.837 回答
0

您必须调用sc.nextLine();两次,因为在给出一些输入后,您按回车键生成换行符。
因此,您可以通过再添加一个来处理这个额外的换行符sc.nextLine();

于 2013-02-13T05:40:19.713 回答