为什么 hasNext() False,但 hasNextLine() 是 True?

2022-08-31 16:10:28

问题

为什么对于扫描仪对象,方法返回 true 而方法返回 false?hasNextLine()hasNext()

注意:基于输入文件,该方法按预期返回结果;似乎没有返回正确的结果。hasNext()hasNextLine()

法典

以下是我正在运行的代码,用于创建以下结果:

public void ScannerTest(Reader fileReaderObject){
    Scanner scannerObj = new Scanner(fileReaderObject);

    for(int i = 1; scannerObj.hasNext(); i++){
        System.out.println(i + ": " + scannerObj.next());
        System.out.println("Has next line: " + scannerObj.hasNextLine());
        System.out.println("Has next: " + scannerObj.hasNext());
    }
    System.out.println();

    scannerObj.close();
}

输入文件

以下是我传递给此扫描程序的文件的实际内容:

a   3   9
b   3   6
c   3   3
d   2   8
e   2   5
f   2   2
g   1   7
h   1   4
i   1   1

结果

以下是我运行代码时在控制台中打印的内容的结尾,其中包括我无法理解的部分:

25: i
Has next line: true
Has next: true
26: 1
Has next line: true
Has next: true
27: 1
Has next line: true
Has next: false

答案 1

您在文件末尾有一个额外的换行符。

  • hasNextLine() 检查缓冲区中是否有另一个。linePattern
  • hasNext() 检查缓冲区中是否存在可解析的令牌,由扫描程序的分隔符分隔。

由于扫描程序的分隔符是空格,并且也是空格,因此缓冲区中可能有一个,但没有可分析的标记。linePatternlinePattern

通常,处理此问题的最常见方法是在解析文本每行中的所有标记(例如数字)后始终调用。在使用时,也需要从 中读取用户的输入时执行此操作。若要将扫描程序前进到此空格分隔符之后,必须 使用 清除行分隔符。请参见: 使用 scanner.nextLine()nextLine()ScannerSystem.inscanner.nextLine()


附录:

LinePattern被定义为与以下内容匹配的模式

private static final String LINE_SEPARATOR_PATTERN =
                                       "\r\n|[\n\r\u2028\u2029\u0085]";
private static final String LINE_PATTERN = ".*("+LINE_SEPARATOR_PATTERN+")|.+$";

默认的令牌分隔符是这样的:Pattern

private static Pattern WHITESPACE_PATTERN = Pattern.compile(
                                            "\\p{javaWhitespace}+");

答案 2

原因是检查是否有更多非空格字符可用。 检查是否有另一行文本可用。文本文件的末尾可能有一个换行符,因此它有另一行,但没有更多不是空格的字符。hasNext()hasNextLine()

许多文本编辑器会自动将换行符添加到文件末尾(如果还没有换行符)。

换句话说,您的输入文件不是这样的(数字是行号):

1. a   3   9
2. b   3   6
3. c   3   3
4. d   2   8
5. e   2   5

其实是这样的:

1. a   3   9
2. b   3   6
3. c   3   3
4. d   2   8
5. e   2   5
6. 

推荐