为什么hasNextLine()永远不会结束?

| 抱歉,这听起来太简单了。我是Java的新手。 这是我用来检查
hasNextLine()
的一些简单代码。当我运行它时,我无法停止它。我以为,如果您不输入任何内容并按Enter键,则可以退出
while
循环。 有人可以向我解释“ 0”在这种情况下如何工作吗?
import java.util.*;

public class StringRaw {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextLine()) {
            String str = sc.nextLine();
        }
        System.out.print(\"YOU\'VE GOT THROUGH\");
    }
}
    
已邀请:
从System.in读取时,默认情况下是从键盘读取的,并且这是一个无限的输入流……它的行数与用户关心的一样。我认为发送EOF的控制序列可能会起作用,例如CTL-Z(或者是CTL-D?)。 看我的ASCII码图表... CTL-C是ETX,CTL-D是EOT;这些都应该可以终止文本流。 CTL-Z是一个不起作用的SUB(但它可能会起作用,因为历史上控件是高度主观的解释)。     
按Ctrl + D终止来自stdin的输入。 (Windows:Ctrl + Z)或从命令提供输入:
echo -e \"abc\\ndef\" | java Program
    
CTRL-D是UNIX / Linux的字符或字节流的结尾,而CTRL-Z是Windows的字符或字节流的结尾(Microsoft DOS最早的历史产物)。 编写好问题代码后,空行将不会退出循环,因为hasNextLine()不会求值为false。在输入字节流中将有一个行终止符。 System.in是来自标准输入(通常是控制台)的字节流。因此,结束字节流将停止循环。尽管nextLine()不会阻止等待输入,但是hasNextLine()会阻止。按照设计,代码终止的唯一方法是在Windows中使用CTRL-Z或在UNIX / Linux中使用CTRL-D终止字节流,这导致hasNextLine()不会阻塞等待输入并返回布尔值false,从而终止while循环。 如果希望它以空行输入终止,则可以在循环继续条件中检查非空行。以下代码演示了如何将使用hasNextLine()和nextLine()的基本问题设计更改为在出现空行或输入字符结尾时终止的问题(即Windows中为CTRL-Z或UNIX /中为CTRL-D Linux)。 while条件中的附加代码使用赋值运算符的功能,其中它们可以像表达式一样求值,以返回分配的值。由于它是一个String对象,因此String.equals()方法可以与评估一起使用。 其他附加代码仅添加了一些打印输出,以使正在发生的事情显而易见。
// HasNextLineEndDemo.java
import java.util.*;

public class HasNextLineEndDemo {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // this code is a bit gee-whiz
        // the assignment expression gets assigned sc.nextLine()
        // only if there is one because of the &&
        // if hasNextLine() is false, everything after the &&
        // gets ignored
        // in addition, the assignment operator itself, if
        // executed, returns, just like a method return,
        // whatever was assigned to str which, 
        // as a String object, can be tested to see if it is empty
        // using the String.equals() method
        int i = 1; // input line counter
        String str = \" \"; // have to seed this to other than \"\"
        System.out.printf(\"Input line %d: \", i); // prompt user
        while (sc.hasNextLine() && !(str = sc.nextLine()).equals(\"\")) {
            System.out.printf(\"Line %d: \", i);
            System.out.println(\"\'\" + str + \"\'\");
            System.out.printf(\"Input line %d: \", ++i);
        } // end while
        System.out.println(\"\\nYOU\'VE GOT THROUGH\");
    } // end main
} // end class HasNextLineEndDemo
    
根据我的理解,如果您以JDBC或任何迭代器作为结果集对象的示例,则在这些情况下,您将获得一组有限的东西,并且每次迭代器都要检查是否已到达集合的末尾。 但是在上述情况下,他们无法知道用户输入的结束,即hasNextLine()无法知道用户何时要终止,因此它会无限进行下去。 最好的方法是将附加条件放在for循环中,以检查for循环中将来会失败的某些条件。 在上面的帖子中,@ Jim \的答案说明了这一点。 实际上,不建议使用hasNextLine()作为控制台输入的循环终止符,因为它永远不会返回false。     
我在套接字输入流中遇到了类似的问题。我发现的大多数解决方案仍然会阻止执行。事实证明,您可以使用InputStream.available()进行无阻塞检查。 因此,在这种情况下,以下方法应该起作用:
int x = System.in.available();
if (x!=0) {
    //Your code
}
    

要回复问题请先登录注册