In java Scanner.next()

2019-08-27 07:27发布

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();
        }
    }
}

Hi, im new to java, as usual im trying out a few things in the Scanner Class.

is there a way to see the input of the scanner? Cuz i have a problem here with the code above as you'll see. this is the output of my console window after i entered wrong data. instead of numbers i entered KKK so can somebody explain me why i got this error message 2 times?

"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: 

3条回答
何必那么认真
2楼-- · 2019-08-27 08:05

The problem is you're calling scanner.nextdouble() which will work fine if and when there is a double in the input. When there is not a double in the input your input that was "KKK" is ignored by the call to nextDouble() and your error message is displayed then when you call nextLine() that same input "KKK" is still there waiting wo when you loop back throught the while the "KKK" is then passed back to your program and since it is still not a double you get the repeated error message.

Try this:

    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();
            }
        }
    }

That will consume the invalid input of "KKK" and let the program continue properly.

查看更多
够拽才男人
3楼-- · 2019-08-27 08:16

Change your code as follows.

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");
        }
    }
}

When you use Scanner.nextDouble(), it does not consume the new line (or other delimiter) itself so the next token returned will typically be an empty string.

查看更多
贼婆χ
4楼-- · 2019-08-27 08:28

I think the real problem is that you have some obfuscation in your loop structure that makes it hard to understand the in and out conditions of the scanner with each iteration of the loop.

Heres what is really happening. We enter the loop with one token in the Scanner which is not a double. We ask is there a double next in the scanner with hasNextDouble(), which since the one token can not be converted to a double, this returns false. We report an error and isValid remains false. After the branch we call scanner.next() and consumer our non double token. We renter the loop since isValid remains false. We again ask if there is a double next in the Scanner. Now the scanner is empty, since we consumed out token, and this call returns false, so we report another error. Now we call scanner.next() again. Since the scanner is now empty, and scanner.next() implements synchronous message passing (I/O), we now block until the scanner recieves a new token, so your program will stall until you input a new token. Try puting in more into your console. You would probably repeat the loop and see another error.

What you want to accomplish is with each loop, consume a token. If that token is a double, accept the input and continue, if not report an error and repeat. Try something like this instead, it should present a more clear picture of what the scanner is doing every loop.

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);
    }
}

Notice i use the wrapper class Double not the primative double. This is so that I can set the double to null, since Double is an Object and not a primitive.

查看更多
登录 后发表回答