как использовать два сканера на одном методе

ранее сегодня я спросил =1#comment92721337_52904883">как повторно попытаться/отловить исключение несоответствия ввода, не попадая в бесконечный цикл

но это процесс из двух процедур, сначала игра спросит у пользователя размер сетки, а позже после запуска попросит его либо установить флаг, либо перешагнуть через ячейку (если моя игра будет окончена, иначе она выведет количество окружающих мин), но я получаю странные ошибки в коде:

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

ошибки:

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

странная вещь, что он печатает сообщения об исключениях между моими операторами печати (сетка - это один оператор, инструкции тоже)

когда я сделал свой поиск, я обнаружил, что я не могу использовать два сканера в одном и том же месте, но как я могу их разделить, если они инициализируются при попытке с ресурсами


person همام بابي خوجة    schedule 20.10.2018    source источник


Ответы (1)


Этот:

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

представляет собой блок попытки с ресурсами. Когда блок завершит выполнение, он вызовет scanner.close().

Проблема с этим для вашего варианта использования заключается в том, что Сканер, в свою очередь, вызывает System.in.close(). Как только поток был закрыт, вы не можете читать из него снова, поэтому вы получите исключение, когда попытаетесь создать еще один сканер, читающий из System.in впоследствии.

Самое простое исправление вашего кода — объединить два блока try-with-resources и повторно использовать один и тот же сканер, чтобы вы не закрывали его между ними. В любом случае нет веской причины иметь два отдельных сканера.

Но на самом деле вы вообще не должны использовать try-with-resources.

Общее правило таково: не закрывать поток, которым вы не владеете, что примерно переводится как не закрывать поток, который вы не открывали, учитывая, что в Java нет понятия "собственность". Вы не открыли System.in, это сделала JVM.

Вы не знаете, что еще в вашей программе зависит от того, что она остается открытой. Если вы закроете такой поток, вы испортите состояние потока для будущих читателей потока.

Теперь вы можете думать, что вам нужно использовать twr, потому что в противном случае ваша IDE помечает сканером предупреждение об утечке ресурсов. В общем, вы можете закрыть сканер; в данном конкретном случае нет. Игнорируйте (или подавляйте) это предупреждение, если именно поэтому вы используете twr.

person Andy Turner    schedule 20.10.2018