0
public class Calculator
{

    public static void main(String[] args)
    {
        boolean isValid = false;
        Scanner myScanner = new Scanner(System.in);
        String customerType = null;
        System.out.print("Customer Type? (C/R) ");
        customerType = myScanner.next();
        while (isValid == false)
        {
            System.out.print("Enter Subtotal: ");

            if (myScanner.hasNextDouble())
            {
                double sobTotal = myScanner.nextDouble();
                isValid = true;
            }
            else
            {
                System.out
                        .println("Hay! Entry error please enter a valid number");
            }
            myScanner.nextLine();
        }
    }
}

嗨,我是 java 新手,我像往常一样在 Scanner 类中尝试了一些东西。

有没有办法查看扫描仪的输入?因为你会看到我上面的代码有问题。这是我输入错误数据后控制台窗口的输出。我输入的是 KKK 而不是数字,所以有人可以解释一下为什么我两次收到此错误消息吗?

"this is the console" 
Customer Type? (C/R) R
Enter Subtotal: KKK
Hay! Entry error please enter a valid number
Enter Subtotal: Hay! Entry error please enter a valid number
Enter Subtotal: 
4

3 回答 3

2

如下更改您的代码。

boolean isValid = false;
Scanner myScanner = new Scanner(System.in);
String customerType = null;
System.out.print("Customer Type? (C/R) ");
customerType = myScanner.next();

while (!isValid)
{
    System.out.print("Enter Subtotal: ");

    if (myScanner.hasNext())
    {
        try
        {
            double sobTotal =Double.parseDouble(myScanner.next());
            isValid = true;
        }
        catch(Exception e)
        {
            System.out.println("Hay! Entry error please enter a valid number");
        }
    }
}

当您使用Scanner.nextDouble()时,它不会使用新行(或其他分隔符)本身,因此返回的下一个标记通常是一个空字符串。

于 2012-07-24T14:52:29.943 回答
1

我认为真正的问题是你的循环结构中有一些混淆,这使得在循环的每次迭代中很难理解扫描仪的输入和输出条件。

这是真正发生的事情。我们在 Scanner 中使用一个令牌进入循环,该令牌不是双重的。我们询问扫描仪中是否有一个 double next with hasNextDouble(),因为无法将一个标记转换为 double,所以返回 false。我们报告错误并isValid保持错误。在分支之后,我们调用scanner.next()并消费我们的非双重令牌。我们租用循环,因为 isValid 仍然为假。我们再次询问扫描仪中是否有双下一个。现在扫描器是空的,因为我们消耗了令牌,并且这个调用返回false,所以我们报告另一个错误。现在我们打电话scanner.next()再次。由于扫描器现在是空的,并且scanner.next() 实现了同步消息传递(I/O),我们现在阻塞直到扫描器接收到一个新的令牌,所以你的程序将停止直到你输入一个新的令牌。尝试在您的控制台中添加更多内容。您可能会重复循环并看到另一个错误。

您想要完成的是在每个循环中,使用一个令牌。如果该标记是双精度,则接受输入并继续,如果不是则报告错误并重复。尝试这样的事情,它应该更清楚地显示扫描仪在每个循环中所做的事情。

public class Calculator
{

    public static void main(String[] args)
    {
        Scanner scan = new Scanner(System.in);

        String customerType = null;

        System.out.print("Customer Type? (C/R) ");
        customerType = scan.next();

        Double test = null;
        do{
            try{
                test = scan.nextDouble();       
            }catch (InputMismatchException ime){ //will be thrown if the token we input is not a double
                System.err.println("Error Message");
            }
        }while(test == null);
    }
}

请注意,我使用包装类Double而不是原始类double。这样我就可以将双精度设置为空,因为Double它是一个Object而不是原语。

于 2012-07-24T15:09:15.470 回答
1

问题是您正在调用scanner.nextdouble(),如果输入中有双精度,它将正常工作。当输入中没有双精度时,对 nextDouble() 的调用将忽​​略您的输入“KKK”,并显示您的错误消息,然后当您调用 nextLine() 时,相同的输入“KKK”仍在等待 wo 时您循环返回,而“KKK”然后被传递回您的程序,并且由于它仍然不是双精度,您会收到重复的错误消息。

试试这个:

    boolean isValid = false;
    Scanner myScanner = new Scanner(System.in).useDelimiter("\\n");
    String customerType = null;
    System.out.print("Customer Type? (C/R) ");
    customerType = myScanner.next();
    while (!isValid)
    {
        System.out.print("Enter Subtotal: ");

        if (myScanner.hasNextDouble())
        {
            double sobTotal = myScanner.nextDouble();
            isValid = true;
        }
        else
        {
            System.out.println("Hay! Entry error please enter a valid number");

            if(myScanner.hasNext()){
              myScanner.next();
            }
        }
    }

这将消耗“KKK”的无效输入并让程序正常继续。

于 2012-07-24T15:09:36.963 回答