Home > Software engineering >  Closing multiple scanners causes problems
Closing multiple scanners causes problems

Time:04-26

I have a function being invoked and I want it to keep looping, but when I take in an input to keep going I get the following error:

Exception in thread "main"
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at SticksGame.main(SticksGame.java:144)

I assume this due to the scanner I am using but I'm not sure why when closing two scanners in the code I get problems. I tried removing one of the scanners closes, but then my code infinitely loops and asks for the same input.

public void begin() {
    while (this.numOfSticks > 0) {

        if (player == 1) {
            doNextTurn(this.player);
        } else if (player == 2 && !isAgainstAi) {
            doNextTurn(this.player);
        } else {
            doAiNextTurn();
        }

        if (this.numOfSticks <= 0) {
            if (this.player == 1 && isAgainstAi) {
                // AI won
                incrementHats(true);
            }
            if (this.player == 2 && isAgainstAi) {
                System.out.println("AI loses.");
                // AI loses
                incrementHats(false);
                // System.out.print("Play again (1 = yes, 0 = no)? ");
                // int pA = scanner.nextInt();
                // printHats();
            } else {
                String message = String.format("Player %s: you lose.", this.player);
                System.out.println(message);
                // printHats();
            }
            scanner.close();
            return;
        }
        this.togglePlayer();
        // printHats();
    }

}
public static void main(String[] args) {
    SticksGame game = new SticksGame();
    Scanner s = new Scanner(System.in);
    game.begin();
    while (true) {
        System.out.println("Play again (1 = yes, 0 = no)? ");
        if (s.next().equals("1")) {
            game.begin();
        } else {
            s.close();
            System.exit(1);
        }
    }
}

CodePudding user response:

There is nothing such as scanner in begin() method. And you don't have to close it if you are closing it in main.

CodePudding user response:

From the JavaDoc of Scanner.close(): "If this scanner has not yet been closed then if its underlying readable also implements the Closeable interface then the readable's close method will be invoked."

Since System.in is an InputStream which implements the Closeable interface, closing a scanner also closes the System.in stream and therefore affects the other Scanner. You get a NoSuchElementException if you try to use it again.

CodePudding user response:

Scanner.close() will close the scanner itself as well as any underlying closeable objects. And Since System.in is managed by the JVM internals, there's no way of re-opening it once it's been closed. You should try to avoid closing any Scanner that wraps System.in.

  • Related