显然,我的真实代码更复杂,但这是一个例子:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in).useDelimiter("\n");
String[] cmdSplit = null;
while (true) {
while (input.hasNext()) {
cmdSplit = input.next().split("\\s+");
System.out.println("stuff");
}
for (int i = 0; i < cmdSplit.length; i++) System.out.println(cmdSplit[i]);
}
}
}
在上面的示例中,代码从System.in
获取输入,将其拆分,并输出每个部分。但是,由于某种原因,内部while
循环之后的代码永远不会执行。如果我将while
替换为if
,则可行。如果你测试它,你可以看到它无法无限运行,因为它只打印“stuff”一次,显示循环运行一次。 while
循环有什么问题?
答案 0 :(得分:3)
从System.in
读取与从文件或其他固定大小的输入源读取不同。在您创建输入之前,输入不一定存在,因此尝试读取它需要block直到输入实际到达(即您键入它)。尝试输入另一行 - 您会再次看到stuff
消息;这将允许.hasNext()
返回,因为现在有输入。
要让.hasNext()
返回false
,需要关闭输入源。对于命令行应用程序,您可以通过发送EOF signal(Linux上的Ctrl + D)来执行此操作,该命令告诉进程stdin没有更多输入。但是,这通常不是您希望程序如何工作的,所以如果您的目的只是阅读一行然后继续,那么您实际上应该使用if
代替while
我试过这样做。稍后,如果您需要阅读更多输入,您将再次致电.hasNext()
,您的程序将阻止,直到用户传递更多输入。
正如@ user7提到的,您的外部while (true)
与while(input.hasNext())
相结合是多余的。如果您只想阅读一次while (true)
并使用if (input.hasNext())
。否则,如果你想永远阅读,只需结合两个循环:
while (input.hasNext()) {
cmdSplit = input.next().split("\\s+");
System.out.println("stuff");
for (int i = 0; i < cmdSplit.length; i++) System.out.println(cmdSplit[i]);
} // Loop will terminate once stdin is closed, e.g. by the user sending EOF.
答案 1 :(得分:-1)
是的,您的代码不会转到for
循环,因为Scanner.hasNext()
将始终听取控制台的输入。
你必须打破循环才能出来并进入for循环。
Scanner input = new Scanner(System.in).useDelimiter("\n");
String[] cmdSplit = null;
while (true) {
while (input.hasNext()) {
cmdSplit = input.next().split("\\s+");
System.out.println("stuff");
break;
}
for (String element : cmdSplit) {
System.out.println(element);
}
}
答案 2 :(得分:-1)
它是印刷的原因&#34;东西&#34;只有一次是因为hasNext()返回false。
让我解释一下我观察到的情况。
获得&#34;东西&#34;无限打印,必须删除作业。意思是一旦你分配了输入,扫描仪就没有任何更多的令牌
The java.util.Scanner.hasNext() method Returns true if this scanner has another token in its input.
这将无限期打印
while (input.hasNext()) {
// cmdSplit = input.next().split("\\s+");
System.out.println("stuff");
}