在以下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
在使用next()或nextFoo()后,从扫描仪查看答案时跳过nextLine()?,我们必须添加Cmd8的原因是,nextInt()一直读取输入,直到将输入发送到程序,并将输入放回输入流的前面。现在,当“Cmd8”中的nextLine()开始读取它时,它会在输入流的开始处发现前面没有任何字符串,它假定用户没有输入任何内容,因此将空字符串作为输入并转到Cmd9
我的疑问是,nextInt()也会一直读到\n(根据我的经验,这意味着Cmd3一直在等待,直到我按下enter键为止)为什么Cmd5一直在等待我的输入。它还应该在输入流的开头找到,并假设我没有输入任何内容,并将空整数作为输入(类似于Cmd8的行为)。这里发生了什么?
请注意以下摘录自Scanner#next文档:
从此扫描仪中查找并返回下一个完整的令牌。完整标记的前面和后面都是与分隔符模式匹配的输入。
扫描器使用的默认分隔符是\p{javaWhitespace},如下所示:
import java.util.Scanner;
public class Main {
public static void main(String... args) {
Scanner input = new Scanner(System.in);
System.out.println(input.delimiter());
}
}
以下几行代码显示了在找到10或hello时如何找到完整的令牌,即无论您按多少次Enter键,都会继续请求输入,直到输入非空白字符。注意:如果是nextInt(),则值10可解析为int,但不是hello,因此将引发输入不匹配异常。
public class Main {
public static void main(String... args) {
System.out.println(Character.isWhitespace('\n'));
System.out.println("\n\n\n\n\n".split("\\p{javaWhitespace}+").length);
System.out.println("10\n".split("\\p{javaWhitespace}+").length);
System.out.println("hello\n".split("\\p{javaWhitespace}+").length);
}
}
输出:
true
0
1
1
这适用于所有的nextXXX()
,除了nextLine(),其文档(以下摘录)非常清楚它与其他nextXXX()的不同之处。
使此扫描仪超过当前行并返回跳过的输入。此方法返回当前行的其余部分,不包括末尾的任何行分隔符。该位置设置为下一行的开头。由于此方法继续在输入中搜索行分隔符,因此如果不存在行分隔符,它可能会缓冲所有要跳过的行的输入搜索。
换句话说,nextLine()
将捕获所有内容,包括直接输入或从上一个输入中剩余的空格字符。
我已经通过调试JRE Scanner类方法分析了您的问题。当您调用nextInt
函数时,Scanner看起来是当前缓冲区。如果没有可用的输入,开始监听键盘,直到您按下Enter
键,整个键盘字符附加到缓冲区并尝试匹配它是否是整数。当找到一个整数nextInt
返回值并增加缓冲区的位置索引。下一步,您再次调用nextInt
,只有\n
字符,然后将其丢弃并等待下一个整数模式。此外,缓冲区的下一个字符又是\n
。当您调用nextLine
时,它会查看缓冲区并打印一个空行。因此第二个nextLine
以空文本开头。
也许这会让人困惑。让我们看看场景:
注:索引表示缓冲区的读取位置。
i1 = input.nextInt();
keyboard = 1 2 {Enter}
buffer = | 1 | 2 | \n |
index = ^
返回12
,下一个缓冲区位置位于\n
java prettyprint-override">i2 = input.nextInt();
keyboard = 3 4 {Enter}
buffer = | 1 | 2 | \n | 3 | 4 | \n |
index = ^
返回34
,下一个缓冲区位置位于第二个\n
input.nextLine();
缓冲区具有\n
字符,因此Scanner不等待键盘并返回值。
buffer = | 1 | 2 | \n | 3 | 4 | \n |
index = ^
返回空文本
s1 = input.nextLine();
keyboard = test {Enter}
buffer = | 1 | 2 | \n | 3 | 4 | \n | t | e | s | t | \n |
index = ^
返回测试
使用 ubuntu22.04 发现使用 sudo apt update && sudo apt upgrade -y 更新软件包的时候,也会更新 Kernel 机器上有好多个 Kernel 了,ubuntu 给我下载这么多 Kernel 干嘛呢?
我在vue3项目中使用了 '@vueuse/gesture' 的useWheel函数来帮助监听滚轮在一个元素上的滑动,但我发现指令能生效,而Composable的写法却不生效,无法触发wheelHandler回调。 我在调用useWheel之前也log了 workspaceArea.value是有值的,正常的。 是我的代码写的有问题吗?还是库的bug?
问题内容: 我正在尝试向div添加ajax响应(它是带有表,表单等的HTML代码)。 在FF中工作完美,但在IE中却给了我一个未知的错误。 我尝试了很多东西,但是只有当我添加jQuery并在要插入代码的div上运行该方法时,它才起作用。 有人在乎解释为什么这样做有效,而不是简单吗?我尝试查看代码,但我想我不是JS的佼佼者,因为我不了解它在做什么。 问题答案: IE 有 多个 文档(pre | ta
所以我有一个OpenGL程序,可以分割屏幕。经过研究,我的代码如下所示: 然而,我不明白它为什么会工作,我肯定错过了OpenGL的一些基本功能。我不明白的部分是在每个“屏幕”的末尾,我画了一个带纹理的四边形(最后5行代码)。但是这种纹理是从哪里来的呢?为什么它恰好是我为屏幕绘制的场景的纹理?我从来没有做过glBindTexture或glEnable(GL_TEXTURE_2D)任何事情,事实上,在
我执行以下代码,没有错误,在输出中我看到了消息。你能解释一下这种奇怪的行为吗? 你可以查看在线演示
问题内容: 假设我们的应用程序只有一个线程。然后我们正在使用,这是什么问题? 我的意思是,如果可以通过同步处理多个线程,那么使用单线程有什么问题? 为什么要改用? 问题答案: 是线程安全的,这意味着它们具有同步的方法来控制访问,因此一次只有一个线程可以访问StringBuffer对象的同步代码。因此,在多个线程可能试图同时访问同一StringBuffer对象的多线程环境中,StringBuffer