在下面的java代码中
Scanner input = new Scanner(System.in); //Cmd1
int i1,i2; //Cmd2
i1 = input.nextInt(); //Cmd3
System.out.println("value of i1 is "+ i1); //Cmd4
i2 = input.nextInt(); //Cmd5
System.out.println("value of i2 is "+ i2); //Cmd6
String s1; //Cmd7
input.nextLine(); //Cmd8
s1 = input.nextLine(); //Cmd9
System.out.println("value of s1 is "+ s1); //Cmd10
我在控制台中得到了以下输出
<myinput> 1
<output> value of i1 is 1
<myinput> 2
<output> value of i2 is 2
<myinput> firstString
<output> value of s1 is firstString
一直等待输入,直到我按下 enter
钥匙。我试过了 tab
,多个 tab
, space
但是它一直在等待,并且没有移动到下一个命令,因此我假设nextint在移动到下一个命令之前会一直等待,直到它在输入流中找到为止。
从scanner查看答案是在使用next()或nextfoo()之后跳过nextline(),这是我们必须添加的原因 Cmd8
是因为nextint()一直读取输入直到 \n
,将输入发送到程序并将 \n
回到输入流前面。现在,当“cmd8”中的nextline()开始读取它时,它会发现 \n
在没有任何前面字符串的输入流开始时,它假定用户没有输入任何内容,因此将空字符串作为输入并转到 Cmd9
.
我的怀疑是因为nextint()也读到了till \n
(根据我的经验 Cmd3
一直等到我按 enter
)为什么是 Cmd5
等待我的意见。它也应该找到 \n
在输入流的开头,假设我没有输入任何内容,并将空整数作为输入(类似于 Cmd8
是行为)。这里发生了什么?
2条答案
按热度按时间p1iqtdky1#
我已经通过调试jre scanner类方法分析了您的问题。当你打电话的时候
nextInt
函数,扫描仪查看当前缓冲区。如果没有可用的输入,请开始收听键盘,直到按Enter
键,将整个键盘字符追加到缓冲区,并尝试匹配它是否为整数。当它是一个整数nextInt
返回值并递增缓冲区的位置索引。下一步,你打电话给nextInt
再说一次,只有\n
字符,然后丢弃它并等待下一个整数模式。另外,缓冲区的下一个字符是\n
再一次。当你打电话的时候nextLine
它查看缓冲区并打印空行。所以第二nextLine
以空文本开始。也许会让人困惑。让我们看看场景:
注:索引
^
表示缓冲区的读取位置。步
退货
12
下一个缓冲位置位于\n
步退货
34
下一缓冲位置位于第二缓冲位置\n
步缓冲区有
\n
字符,所以扫描仪不会等待键盘并返回值。退货
empty text
步退货
test
envsm3lx2#
请注意以下摘录自
Scanner#next
文档:查找并返回来自此扫描仪的下一个完整令牌。完整的标记前面和后面是与分隔符模式匹配的输入。
使用的默认分隔符
Scanner
是\p{javaWhitespace}+
具体如下:下面的代码行显示了如何尽快找到一个完整的令牌
10
或者hello
即无论按多少次回车键,next()
,nextInt()
etc将一直请求输入,直到输入非空白字符。注:如果nextInt()
,值10
可解析为int
但是hello
不是因此InputMismatchException
将被抛出。输出:
这适用于所有
nextXXX()
除外nextLine()
其文档(节选如下)非常清楚它的行为与其他nextXXX()
.使扫描器超过当前行并返回跳过的输入。此方法返回当前行的其余部分,不包括末尾的任何行分隔符。该位置设置为下一行的开头。由于此方法继续在输入中搜索寻找行分隔符,因此如果不存在行分隔符,它可能会缓冲所有搜索该行的输入。
换句话说,
nextLine()
将捕获所有内容,包括直接输入的空白字符或上一次输入的剩余字符。