Странная ошибка со сканером Java при вводе пользователем - PullRequest
0 голосов
/ 06 апреля 2020

Я работаю над проектом Java, который включает в себя простую систему меню. Я получаю некоторые странные ошибки, когда код достигает следующей строки в функции Menu ():

int menuInput = Integer.parseInt(scanner.nextLine()); 

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

package Compiler;

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import java.io.IOException;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
        System.out.println("Copy and paste code to be compiled here, then press ENTER followed by CTRL+D:\n");

        CharStream input = CharStreams.fromStream(System.in);
        GrammarLexer lexer = new GrammarLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        GrammarParser parser = new GrammarParser(tokens);
        ParseTree tree = parser.program();
        Worker worker = new Worker(parser.getRuleNames());
        worker.visit(tree);
        Menu(worker);
    }

    private static void Menu(Worker worker) {
        while (true) {
            System.out.println("1-4?");

            Scanner scanner = new Scanner(System.in);
            int menuInput = Integer.parseInt(scanner.nextLine());   // THIS IS WHERE THE CODE CRASHES

            try {
                switch(menuInput) {
                    case 1: {
                        worker.PrintParseTree();
                        break;
                    } case 2: {
                        String searchQuery = scanner.nextLine();
                        worker.SearchParseTree(searchQuery);
                        break;
                    } case 3: {
                        worker.PrintJSCode();
                        break;
                    } case 4: {
                        worker.PrintWACode();
                        break;
                    } default: {
                        System.out.println("ERROR: Invalid input, please try again...");
                        break;
                    }
                }
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    }
}

Это ошибка, которая продолжает возникать. Сбой кода перед предоставлением пользователю возможности сделать какой-либо ввод:

Exception in thread "main" java.util.NoSuchElementException: No line found
    at java.base/java.util.Scanner.nextLine(Scanner.java:1651)
    at Compiler.Main.Menu(Main.java:44)
    at Compiler.Main.main(Main.java:29)

Обновление: Исходя из того, что выглядит на веб-сайте ANTLR, метод fromStream откроет поток System.in, а затем закроет его (см. Цитату из веб-сайт).

Создает CharStream на основе открытого InputStream, содержащего байты UTF-8. Перед возвратом считывает все содержимое InputStream в результат, а затем закрывает InputStream.

Кто-нибудь может предложить обходной путь для этого?

1 Ответ

0 голосов
/ 06 апреля 2020

Я думаю, что где-то внутри рабочих методов вы закрываете вход CharStream, который закрывает System.in, что означает, что больше нет строк для чтения сканером.

Редактировать:

У меня нет доступа к классу CharStream, поэтому я заменил его на InputStreamReader в моем примере. Следующий код выдает ту же ошибку, что и ваша.

//When the program starts, System.in is open.

InputStreamReader is = new InputStreamReader(System.in);
is.close(); 
// When we close the InputStreamReader, the underlying System.in is also closed.

Scanner scanner = new Scanner(System.in); 
//It successfully creates a scanner for System.in, even if it's closed.

scanner.nextLine();
//But it can't read, since the underlying stream is now closed.

Меня не волнуют случаи System.in.close(), а скорее input.close(), что также влияет на System.in. input может, конечно, иметь разные имена в разных классах.

...