为什么 hasNextLine() 永无止境?

2022-09-03 00:19:54

抱歉,如果这听起来太简单了。我对Java很陌生。

以下是我用来检查的一些简单代码。当我运行它时,我无法让它停止。我以为如果你不写任何输入并按下,你会逃脱循环。hasNextLine()Enterwhile

有人可以向我解释在这种情况下是如何工作的吗?hasNextLine()

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");
    }
}

答案 1

当从 System.in 读取时,默认情况下,您正在从键盘读取,这是一个无限的输入流...它具有用户想要键入的行数。我认为发送EOF的控制序列可能会起作用,例如CTL-Z(或者它是CTL-D?)。

看看我的好人ASCII图表...CTL-C是ETX,CTL-D是EOT;其中任何一个都应该用于终止文本流。CTL-Z是一个不应该工作的SUB(但它可能会,因为控件在历史上被高度主观地解释)。


答案 2

CTRL-D是UNIX/Linux的字符或字节流的结尾,CTRL-Z是Windows的字符或字节流的结尾(这是Microsoft DOS早期的历史产物)。

编写问题代码后,空行不会退出循环,因为 hasNextLine() 的计算结果不会为 false。它将在输入字节流中有一个行终止符。

System.in 是来自标准输入(通常是控制台)的字节流。因此,结束字节流将停止循环。虽然 nextLine() 不会阻止等待输入,但 hasNextLine() 会阻止输入。按照设计,代码终止的唯一方式是Windows中的CTRL-Z或UNIX/ Linux中的CTRL-D,它结束字节流,导致hasNextLine()不阻止等待输入并返回一个布尔假,终止while循环。

如果您希望它以空行输入终止,则可以检查非空行作为循环继续条件的一部分。下面的代码演示如何将使用 hasNextLine() 和 nextLine() 的基本问题设计更改为在获得空行或输入字符结尾(即 Windows 中的 CTRL-Z 或 UNIX/Linux 中的 CTRL-D)时终止的问题设计。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

推荐