Java Scanner在接受用户输入时出现奇怪的错误。

huangapple 未分类评论42阅读模式
英文:

Strange error with Java Scanner when taking user input

问题

我正在处理一个包含简单菜单系统的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("将要编译的代码复制粘贴到这里,然后按ENTER,然后按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());   // 这是代码崩溃的地方

            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("错误:无效的输入,请重试...");
                        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,给定一个包含UTF-8字节的打开InputStream。在返回之前,将整个InputStream的内容读入结果,然后关闭InputStream。

是否有人可以为此提供解决方法?

英文:

I am working on a Java project that includes a simple menu system. I am getting some strange errors when the code reaches folling line in the Menu() function:

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

I have seen similar issues that people have posted, but nothing I do seems to fix the issue. I have posted the full class below.

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

This is the error that continues to occur. The code crashes before giving the user opportunity to make any input:

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)

Update:
From looks of things from ANTLR website, the fromStream method will open the System.in stream, then closes it (see quote from website).

> Creates a CharStream given an opened InputStream containing UTF-8
> bytes. Reads the entire contents of the InputStream into the result
> before returning, then closes the InputStream.

Can anybody provide a workaround for this?

答案1

得分: 0

我认为在工作方法的某个地方,您关闭了CharStream输入,这将关闭System.in,这意味着扫描器没有更多行可以读取。

编辑:

我无法访问CharStream类,所以我在我的示例中将其替换为InputStreamReader。以下代码产生与您的代码相同的错误。

// 程序启动时,System.in是打开的。

InputStreamReader is = new InputStreamReader(System.in);
is.close(); 
// 当我们关闭InputStreamReader时,底层的System.in也会关闭。

Scanner scanner = new Scanner(System.in); 
// 即使System.in被关闭,它仍然成功地为其创建了一个扫描器。

scanner.nextLine();
// 但是由于底层流现在已关闭,它无法读取。

我关心的不是System.in.close()的实例,而是同样会影响System.ininput.close()。当然,在不同的类中,input可能会有不同的名称。

英文:

I think somewhere inside of the worker methods you close the CharStream input, which closes System.in, which means there are no more lines for the scanner to read.

Edit:

I don't have access to the CharStream class, so I substited it for InputStreamReader in my example. The following code gives the same error that yours does.

//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.

I'm not concerned about instances of System.in.close(), but rather input.close() which also affects System.in. input may of course have a different name in different classes.

huangapple
  • 本文由 发表于 2020年4月6日 22:18:00
  • 转载请务必保留本文链接:https://java.coder-hub.com/61061916.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定