首页 文章

为什么Java要我再次按Enter键?

提问于
浏览
14

我一直在绞尽脑汁想要了解Scanner的工作原理 . 所以这是代码:

Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
String p = sc.nextLine();
System.out.println(s);
System.out.println(p);
System.out.println(sc.hasNextLine());

expect

Love is good  <- press ENTER
Love is blind <- press ENTER
Love is good  <- output
Love is blind <- output
false

have

Love is good   <- I press ENTER
Love is blind  <- I press ENTER
Love is good   <- output
Love is blind  <- output
<- press ENTER
true <- output

do not understand

  • 而不是立即打印此行 - System.out.println(sc.hasNextLine()); - 它让我再次按ENTER键

  • 当没有更多的行或符号时,它会输出true而不是false

have read :我已经读过十几个关于在nextInt()之后使用hasNextLine()的stackoverflow答案,以及关于nextInt()如何不使用行中的最终符号但是我不在这里使用nextInt(),我仍然需要再按一次ENTER,以及为什么hasNextLine()为true .

6 回答

  • 14

    而不是 Scanner 使用 BufferedReader 如此:

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    class Test {
        public static void main(String[] args) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    
            String s = reader.readLine();
            String p = reader.readLine();
            System.out.println(s);
            System.out.println(p);      
            System.out.println(reader.ready());
        }
    }
    

    有关此问题的更多信息,请查看herehere . 根据经验,当你需要解析东西时(如 nextInt )使用 Scanner ,否则坚持 BufferedReader . BufferedReader也比 Scanner 快很多 .

    至于为何你遇到麻烦的行为,请参阅扫描仪的javadoc .

    适用于您的特定情况的部分是:

    扫描操作可能会阻止等待输入 .

    在您的情况下,这意味着:在 Scanner 读取前两行之后, Scanner 正在等待输入,由其方法调用 sc.hasNextLine() 引起 . 然后当Enter被命中时,它得到一个输入(因此它打印 true ,根据docs,当有输入时它返回 true ) . 在方法调用 sc.hasNextLine() 之后,程序中没有更多的可执行行,程序结束,给出了它需要两次输入命中的错觉 .

  • 6

    来自Scanner documentation(由我强调):

    public boolean hasNextLine()
    

    如果此扫描仪的输入中有另一行,则返回true . 此方法可能在等待输入时阻塞 . 扫描仪不会超过任何输入 .

    可能发生的是 hasNextLine 正在阻塞,因为它正在等待输入,您可以通过按Enter键来输入 .

  • 9

    首先,你使用的是向System.in声明的Scanner,这意味着你要求.in检查它们是否还有更多值,等待用户输入内容,然后在按Enter键后显然它返回true .

    所以如果你想检查s或p声明Scanner像这样:

    Scanner sc = new Scanner(s);
    

    要么

    Scanner sc = new Scanner(p);
    

    然后检查 sc.hasNextLine(); 这应该返回false我知道但是对于用户输入我建议创建另一个Scanner变量然后从用户获取值并使用sc作为 hasNextline() 事物 .

    我希望第一个逻辑可以帮助你 .

  • 11

    You are asking for three lines of input!

    在您关闭终端之前,标准输入总是还有一条线路 . 在Unix系统上,您可以在结尾按Ctrl D,它将返回 flase (=输入已关闭) .

    如果您输入有限,程序将按预期运行 . 但互动输入: how does the program know the user does not intend to input Shakespeare next

    函数 hasNextLine()wait for new input to arrive (或者对于不能有新输入的信号) . 此功能不适用于“用户是否已输入另一行" but instead means "等待下一行” . 因此,出于实际目的, hasNextLine() 等同于“用户输入是否仍然连接,并且最终可能包含另一行” .

    你为什么需要最后一行?只需删除它!

  • 0

    你有问题,Scanner正在读取给定的InputStream,它可能类似于文件或者你的情况System.in .

    answer中所述,文件结束, sc.hasNextLine() 将返回false . 通过使用流,您可能希望它无法提供输入数据,因此会阻塞并等待您的下一个输入 .

    也许你可以想到一些“退出的char”(这里是'#'):

    Scanner sc = new Scanner(System.in);
    StringBuilder builder = new StringBuilder();
    while (sc.hasNextLine()) {
        String line = sc.nextLine();
        if (line.equals("#")) {
            break;
        }
        builder.append(line + "\n");
    }
    System.out.println(builder.toString());
    sc.close();
    
  • 10

    在你的情况下,我调试了你的例子并看到了

    System.out.println(sc.hasNextLine());
    

    line等待新输入 . 这既不是真也不是假 . 它不存在 . 这就是它阻止应用程序的原因 . 无论你输入什么(输入或键盘上的任何其他按钮),它都会给你真实,因为你提供了一个新的输入 .

相关问题