简体   繁体   中英

While loop executing once before prompt

This was a difficult question to research, so please forgive me if this is a duplicate.

Basically, I have a while loop that'll only break if a code the user scans is an integer. I check this by trying Integer.parseInt(integer) and only breaks the loop if a NumberFormatException isn't thrown.

My problem, is that when the loop executes for the first time, the exception is thrown, without any user input.

Here's my code:

Scanner input = new Scanner(System.in);

while (true) 
{
    System.out.print("Please scan barcode: ");
    int inCode = 0;

    try
    {
        inCode = Integer.parseInt(input.next());
    }
    catch (NumberFormatException e)
    {
        System.out.println("Numbers only, please.");
    }

    if (inCode != 0) {
    // Do Stuff
    } else {
    System.out.println("Code can't be zero!");
    }
}

What should happen, is this:

Please scan barcode: // And here they enter the barcode

But instead this happens:

Please scan barcode: Numbers only, please.
Please scan barcode:

EDIT:

As per Bohemian's answer, I added the continue keyword to my code. That solves the issue, but only halfway. As per the request of the people who put my question on hold (With good reason, as I now see) I'll post a SSCCE for you guys. I'm going to remove the methods for interfacing with the database, though, only keeping the path that has the problem: creating a new account based on the code.

Scanner input = new Scanner(System.in);

while (true)
{
        System.out.print("Please scan barcode: ");
        int inCode = 0;

        try
        {
            inCode = Integer.parseInt(input.next());
        }
        catch (NumberFormatException e)
        {
            System.out.println("Numbers only, please.");
            continue;
        }

        if (true) // Here it checks if an account associated with the code entered exists in the database. Because I'm having issues when it creates a new account, I've made this true.
        {
            System.out.println("No account associated with that code! Create one?");
            System.out.print("(yes/no): ");
            String answer = input.next();
            if (answer.equalsIgnoreCase("yes"))
            {
                System.out.println("Alright.");
                System.out.print("Please enter a name: ");
                String name = input.next();
                System.out.print("Alright. Now I'll add that to the database... ");

                // Here I add that to the database. Omitted.

                System.out.println("Done! Please scan again to interface.");
            }
            else if (answer.equalsIgnoreCase("no"))
            {
                System.out.println("Okay then.");
            }
            else
            {
                System.out.println("Defaulting to no.");
            }
        }
}
// I still haven't written the code to interface with the account.

What happens now is, it says (in the first iteration)

Please scan barcode:

But, after going through the process of adding the account, it loops again and says:

Please scan barcode: Numbers only, please.
Please scan barcode:

EDIT:

Please note, everything is inside a while loop, so that when everything that the user has done is finished, it'll return to:

Please scan barcode:

I think what you want is this:

Scanner input = new Scanner(System.in);
while (true) {

    System.out.print("Please scan barcode: ");
    int inCode = 0;

    try {
        inCode = Integer.parseInt(input.next());
        if (inCode != 0) {
            // Do Stuff
            break;
        }
    } catch (NumberFormatException e) {
        System.out.println("Numbers only, please.");
    }
}

The code you have could be structured better, which would both make it clearer what is happening and easier to track down problems. You only want to loop on the data input - so just loop on the data input:

int inCode = 0;
while (true) {
    System.out.print("Please scan barcode: ");

    try {
        inCode = Integer.parseInt(input.next());
        break;
    } catch (NumberFormatException e) {
        System.out.println("Numbers only, please.");
    }
}

// Do stuff

You should consider using scanner.hasNextInt() and scanner.nextInt() rather than scanner.next() though. This will also avoid the need for using the exception like this. Normally using Exceptions to control program flow is a bad idea - really they should be used for handling exceptional circumstances. Integer.parseInt doesn't give you any alternatives, but scanner does.

After the edits, it's clear what the problem is: your while (true) loop doesn't have a break statement in it, so it will keep looping forever.

Personally, I'd suggest moving most of your code out of the loop, and only keeping the barcode-parsing code in it, eg like this:

int inCode;
while (true) {
    System.out.print("Please scan barcode: ");   
    try {
        inCode = Integer.parseInt(input.next());
        if (inCode == 0) {
            System.out.println("Code can't be zero!");
        } else {
            break;  // we got a valid barcode! end the loop and move on...
        }
    } catch (NumberFormatException e) {
        System.out.println("Numbers only, please.");
        // no need for a "continue" here, since the loop will restart anyway
    }
}

// rest of the code here...

or possibly even:

int inCode;
while (true) {
    System.out.print("Please scan barcode: ");   
    try {
        inCode = Integer.parseInt(input.next());
    } catch (NumberFormatException e) {
        System.out.println("Numbers only, please.");
        continue;
    }
    if (inCode == 0) {
        System.out.println("Code can't be zero!");
        continue;
    }
    break;  // we have a valid barcode! end the loop and move on...
}

// rest of the code here...

I would just continue the loop if there's bad input, then you don't need to test it later:

while (true) {
    System.out.print("Please scan barcode: ");
    int inCode = 0;

    try {
        inCode = Integer.parseInt(input.next());
    } catch (NumberFormatException e) {
        System.out.println("Numbers only, please.");
        continue; // ADDED THIS LINE
    }

    // Do Stuff with inCode
}

Note that by your code testing for zero after the input, you preclude zero as valid input. This code allows any number, including zero. Small point, but there's no worries about edge cases.

You can try this

String in=null;
while (true) {
    System.out.print("Please scan barcode: ");
    int inCode = 0;
    try {
        in= input.next();
        inCode=Integer.parseInt(in);
    } catch (NumberFormatException e) {
        System.out.println("Numbers only, please.");
    }

if (inCode != 0) {
// Do Stuff
} else {
// Repeat loop
}

or you can directly read an integer through Scanner object instead of using Integer.parseInt() method.

int inCode=0;
while(true) {
  System.out.print("Please scan barcode : ");
  inCode=input.nextInt();

  if(inCode!=0){ //do stuff }
  else { //Repeat Loop }
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM