我想将问题输出到控制台,然后获得输入的下一行之后问题的输出。
例如,我的程序可能正在休眠或正在进行一些耗时的计算,而在用户等待时,他们可能决定在控制台中键入一些注释(也许没有按回车键,或者可能跨越了几行)。睡眠完成后,程序将询问用户一个问题,“您叫什么名字?”然后它应该等待包含用户名的输入的next行,并忽略用户在进行睡眠时所做的任何随机记录。
这里有一些代码试图做到这一点:
public static void main(String[] args) throws InterruptedException {
Scanner scanner = new Scanner(System.in);
Thread.sleep(10_000);
System.out.println("What is your name?");
// while (scanner.hasNext()) {
// scanner.nextLine();
// }
String name = scanner.nextLine();
System.out.println("Hi, " + name);
}
当我在睡眠中输入几行时,其行为如下:
gpeo
hpotWhat is your name?
Hi, gpeo
问题是扫描程序将从读取的最后一个输入开始读取下一个输入,而不是从最后一个System.out.println()
开始读取(这很有意义)。注释掉的代码尝试通过先读取所有较早的输入,然后再等待一行以分配给name
来纠正该问题。但是,scanner.hasNext()
不能按我希望的那样工作,因为当没有下一个令牌时,它不会简单地返回false而是等待另一个令牌(因此我根本不知道为什么麻烦返回一个布尔值)。 >
让我感到困惑的另一件事是,在睡眠期间,如果您在一行上键入内容,那么实际上这<< does >>会被忽略:
brbr irgjojWhat is your name?
A
Hi, A
我以为它将输出Hi, brbr irgjojA
,所以让我觉得我可能误会了控制台输入和Scanner
的工作方式。编辑:最后一个示例来自IntelliJ中的运行。当我从Bash命令行运行时,得到的是
Hi, brbr irgjojA
。不过,第一个示例的输出不会更改。
[另外,有人问我这个问题是否和this相同,显然我必须解释为什么不在这里,否则它将出现在问题上。该帖子(和其他类似的帖子)中的问题在于,他/她正在将scanner.nextLine()
与scanner.nextInt()
以及类似的方法混合使用,从而无法读取整行或行尾。我仅使用nextLine()
来读取输入,但是我的问题大不相同。
进一步编辑
public static void main(String[] args) throws InterruptedException, IOException {
Scanner scanner = new Scanner(System.in);
Thread.sleep(10_000);
System.out.println("What is your name?");
while (System.in.available() > 0) {
scanner.nextLine();
}
String name = scanner.nextLine();
System.out.println("Hi, " + name);
}
这是IntelliJ中的一些测试运行:
grgWhat is your name? A Hi, A ghr rhWhat is your name? A Hi, A rghr hrh htWhat is your name? Hi, hrh uirh iw hjrt sfWhat is your name? Hi, iw
这是Bash中的类似测试:
htrWhat is your name? A Hi, htrA rgj hrWhat is your name? A Hi, hrA rjkh ry jWhat is your name? Hi, ry ryi rj rd jrWhat is your name? Hi, rj
如您所见,由于某种原因,while循环内的行似乎从未执行过多次。我尝试在循环中添加睡眠或使用其他InputStream
和skip()
和readAllBytes()
方法,但这些方法似乎根本没有帮助。我认为对于Bash来说,对于不完整的行可能没有任何办法,但是我敢肯定,必须有一种方法来淘汰所有已完成的行(而不只是第一行)。该解决方案不必使用
Scanner
,它应该可以按预期运行。
我想将问题输出到控制台,然后在输出问题后获取下一行输入。例如,我的程序可能正在休眠或正在进行一些耗时的计算,并且...
Scanner
使用缓冲区。默认大小为1024个字符。因此,通过第一个nextLine()
调用,它将最多1024个可用字符读入缓冲区。这是必要的,因为Scanner
在填充缓冲区并在缓冲区中搜索换行符之前甚至都不知道下一行有多少个字符。因此,如果未决字符少于缓冲区大小,则循环将仅迭代一次。但是,即使有更多的字符和更多的循环迭代,结果状态也可能是缓冲区中有一些挂起的行。