简体   繁体   中英

How can I close a scanner that is inside of a loop?

This code works, but I'm left with a scanner that isn't closed, and when I try to close it, it results in a continuous loop. How can I close this scanner without it resulting in a continuous loop.

Here is my code:

    double startingAmount = 0;

    //Asks how much money customer has to spend, and will re-ask if an invalid input is put in.
    System.out.println("Please enter how much money you have to spend (enter -1 to shut down):");
     int x = 1;

     do {

     try {
         Scanner scanner = new Scanner(System.in);  
         startingAmount = scanner.nextDouble();
         x = 2;

     } catch (Exception e) {
         System.out.println(
                 "Invalid input, please enter how much money you have to spend (enter -1 to shut down):");             
     }

 } while (x == 1);  

Don't. Open it before the loop. Normally you would close it after the loop, but as it wraps System.in you should not close it at all.

Closing a IO Stream (which is what System.in is for the keyboard) is always a good idea so as to remove a potential resource leaks however in this particular case (being a console app) you should only Close a Scanner (using System.in) when you know you're completely finished with it. In your case it will close automatically when your simple application ends. Once you close Scanner which is using System.in , you will not be able to use System.in again during the current application session.

Create your instance of scanner above the do/while loop. It's not a good idea to do it within the loop.

As your code is currently written, only the Scanner.nextDouble() method requires the try/catch . Try to use proper Exceptions - It would be better to use InputMismatchException rather than just Exception .

Your initial prompt would be better placed within the beginning of you do/while loop removing the need for double prompting. Allow the catch block to merely indicate an Invalid Entry.

Using do/while(true) or while(true){} may work better for you here rather than the use of the integer variable x and then in place of x = 2; use break; . The way you're doing it with the int variable will work just fine and there is nothing wrong with it, as long as it will satisfy the condition for the loop and will at some point definitely exit that very same loop. I just find it cleaner using while(true) and break; for something as simple as this. Of course this is just opinion based which we like to try and avoid.

You should place scanner.nextLine(); directly after the catch code block to clear the Scanner buffer since nextDouble() (or nextByte() , nextShort() , nextInt() , nextLong() , nextFloat() , etc) does not provide the newline character to do so. This will eliminate continuous looping on an Invalid Entry.

StackOverflow has lots of examples of how to achieve what you are doing. You just need the yearning to search for them. Even placing something obscure like " how to prompt user in java console " into Google will produce around 4 million results.

Scanner implements the java.io.Closeable interface. Consequently you can instantiate new Scanner instances using the try-with-resources construct.

If you really have to create your Scanner inside the do/while loop, you can do something similar to this:

public static void main(String[] args) {
    double startingAmount = 0;

    //Asks how much money customer has to spend, and will re-ask if an invalid input is put in.
    System.out.println("Please enter how much money you have to spend (enter -1 to shut down):");
    int x = 1;

    do {
        try (Scanner scanner = new Scanner(System.in)) {
            startingAmount = scanner.nextDouble();
            x = 2;
        }
    } while (x == 1);
}

However it might be a better idea to create the Scanner once using try-with-resources and add your loop inside the try block:

public static void main(String[] args) {
    double startingAmount = 0;

    //Asks how much money customer has to spend, and will re-ask if an invalid input is put in.
    System.out.println("Please enter how much money you have to spend (enter -1 to shut down):");
    int x = 1;

    try (Scanner scanner = new Scanner(System.in)) {
        do {
            startingAmount = scanner.nextDouble();
            x = 2;
        } while (x == 1);
    }
}

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