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

时间:2016-01-17 09:33:57

标签: java java.util.scanner

我一直在绞尽脑汁试图理解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());

期望

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

拥有

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

不理解

  1. 而不是立即打印此行 - System.out.println(sc.hasNextLine()); - 它让我再次按ENTER
  2. 当没有更多的行或符号
  3. 时,它会输出true而不是false

    已阅读:我已经阅读了关于在nextInt()之后使用hasNextLine()以及nextInt()如何不使用final的十几个stackoverflow答案行中的符号,但我不明白为什么,即使我不在这里使用nextInt(),我仍然需要再按一次ENTER,为什么hasNextLine()为真。

6 个答案:

答案 0 :(得分: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快很多。

至于您为什么遇到麻烦的行为,请参阅Scanner的{​​{3}}。

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

  

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

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

答案 1 :(得分:11)

来自Scanner documentation(我强调):

public boolean hasNextLine()
  

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

可能发生的事情是hasNextLine正在阻止,因为它正在等待输入,您可以按Enter键进行输入。

答案 2 :(得分:10)

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

因此,如果您想检查s或p声明扫描器,请执行以下操作:

Scanner sc = new Scanner(s);

Scanner sc = new Scanner(p);

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

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

答案 3 :(得分:9)

您正在询问三行输入!

标准输入总是还有一行,直到您关闭终端。在Unix系统上,您最后可以按Ctrl + D,它将返回flase(=输入已关闭)。

如果您有有限输入,程序将按预期运行。但是交互式输入:程序如何知道用户不打算下次输入莎士比亚

函数hasNextLine()等待新输入到达(或者对于无法输入新信号的信号)。此功能不适用于用户输入另一行&#34;但相反意味着&#34; 等待以获得下一行&#34;。因此,出于实际目的,hasNextLine()等同于&#34;用户输入是否仍然连接, 它最终包含另一行&#34;。

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

答案 4 :(得分:6)

您遇到问题,Scanner正在从给定的InputStream中读取,这可能类似于文件或您的System.in

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

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

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

答案 5 :(得分:0)

在您的情况下,我调试了您的示例并看到了

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

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