how to use two scanners on one method

非 Y 不嫁゛ 提交于 2019-12-04 06:17:38

问题


earlier today I asked how to re-try/catch input mismatch exception without getting caught by infinite loop

but it's two procedures process, at first the game will ask the user for the size of the grid and later after the launch it will ask him either to set up a flag or step over a cell(if mine the game will be over else it will print out the number of surrounding mines), but I get some weird errors the code:

int gridSize = 0;
    try (Scanner scanner = new Scanner(System.in)) {
        System.out.println("how much the size of the grid do you want");
        while (!scanner.hasNextInt()) {
            System.err.println("Try again, this time with a proper int");
            scanner.next();
        }
        gridSize = scanner.nextInt();
    }
    MinesWeeper grid = new MinesWeeper(gridSize);
    grid.printOut();

    int choice = 0;
    try (Scanner scanner = new Scanner(System.in)) {
        System.out.println("1-to step over a cell\n2-to set a flag on the cell");
        while (!scanner.hasNextInt()) {
            System.err.println("Try again, this time with a proper int");
            scanner.next();
        }
        choice = scanner.nextInt();
    }

    boolean Continue = true;
    while (Continue) {
        switch (choice) {
            case 1:
                if (grid.chooseCell(1)) {
                    Continue = false;
                }
                break;
            case 2:
                grid.chooseCell(2);
                break;
        }
    }

errors:

how much the size of the grid do you want 3 A B C
Try again, this time with a proper int 1 * * * Exception in thread "main" java.util.NoSuchElementException 2 * * * at java.util.Scanner.throwFor(Scanner.java:862) 3 * * * 1-to step over a cell at java.util.Scanner.next(Scanner.java:1371) at Array.Main.main(MinesWeeper.java:188) 2-to set a flag on the cell

the weird thing that it prints exceptions messages between my printing statements(the grid is one statement, instructions are one too)

when I made my search I found that I can't use two scanners on the same spot, but how can I separate them if they initialized on try with resources


回答1:


This:

try (Scanner scanner = new Scanner(System.in)) {
  // ...
}

is a try-with-resources block. When the block finishes executing, it will call scanner.close().

The problem with that, for your use case, is that the Scanner, in turn, invokes System.in.close(). Once a stream has been closed, you can't read from it again, so you will get an exception when you try to create another Scanner reading from System.in subsequently.

The most trivial fix to your code is to merge the two try-with-resources blocks, and reuse the same Scanner, so you don't close it in between. There is no good reason to have two separate scanners anyway.

But actually, you shouldn't be using try-with-resources at all.

The general rule is not to close a stream that you don't own, which roughly translates to don't close a stream you didn't open, given that Java has no concept of "ownership". You didn't open System.in, the JVM did.

You don't know what else in your program is relying on it continuing to be open. If you do close such a stream, you mess up the state of the stream for future readers of the stream.

Now, you may think that you need to use twr, because your IDE flags a resource leak warning on the Scanner otherwise. In general, you may want to close a Scanner; in this specific case, you do not. Ignore (or suppress) that warning, if that is why you are using twr.



来源:https://stackoverflow.com/questions/52907500/how-to-use-two-scanners-on-one-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!