【问题标题】:Java scanner works from second timeJava 扫描器从第二次开始工作
【发布时间】:2017-12-04 17:10:40
【问题描述】:

我试图在按下控制台输入后调用一个方法。问题是从我第二次按 Enter 键开始调用方法。第一次按 Enter 后如何调用我的方法?

public void read() {
    Scanner scanner = new Scanner(System.in);
    System.out.println("Press Enter to continue");
    try {
        System.in.read();
    } catch (IOException e) {
        e.printStackTrace();
    }
    if (scanner.hasNextLine()) {
        this.win();
    }
}
public void win() {
    if (true) {
        this.read();
    }
}

【问题讨论】:

  • 这是一种不寻常的代码结构,因为这两个函数以看似无限递归的方式相互调用。这是故意的吗?
  • 是的。每次都必须按回车继续

标签: java console java.util.scanner


【解决方案1】:

Scanner 看到之前,等待Enter 被按下的代码会从输入流中“窃取”该字符。因此,第一个 '\n'System.in.read() 行消耗。

当您基于控制台调用scanner.hasNextLine() 以获得Scanner 时,代码会阻塞以查看最终用户是输入一行还是终止流。 hasNextLine 方法返回需要第二个 '\n'

您可以通过删除对System.in.read() 的调用并调用getNextLine() 在下次调用之前使用输入来解决此问题:

public void read() {
    Scanner scanner = new Scanner(System.in);
    System.out.println("Press Enter to continue");
    try {
        System.in.read();
    } catch (IOException e) {
        e.printStackTrace();
    }
    if (scanner.hasNextLine()) {
        scanner.nextLine(); // Remove '\n' from the buffer
        this.win();
    }
}

【讨论】:

  • 问题是我触发了另一个方法2,我想再次回到方法1(按任意键),当按下回车键进入方法2
  • @TeodorKolev 调用 scanner.hasNextLine() 将阻塞,直到按下 Enter。你甚至不需要检查它的返回值。
  • 我不明白
  • 我正在尝试在输入时在两种方法之间切换
  • 在您当前的解决方案中,第一次后它没有再次提示并等待再次按回车
【解决方案2】:

您不需要System.in.read();。如果此扫描仪的输入中有另一行,java.util.Scanner.hasNextLine() 方法将返回 true。此方法在等待输入时可能会阻塞。

public class MyClass {
    public static void main(String args[]) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Press Enter to continue");

        if (scanner.hasNextLine()) {
             System.out.println("Victory!");
        }
    }
}

基本上,您的代码会等待用户在两点按任意键。首先是System.in.read();,然后是scanner.hasNextLine()。这就是为什么您需要在控制台上打印victory 之前按两次 Enter 键。从您的代码中删除 System.in.read();scanner.hasNextLine() 将解决此问题。

【讨论】:

  • 问题是我触发了另一个方法2,我想再次回到方法1(按任意键),当按下回车键进入方法2