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

时间:2015-08-13 16:09:55

标签: java java.util.scanner

问题

对于扫描程序对象,如果hasNextLine()方法返回false,hasNext()方法返回true,该怎么办?

注意:根据输入文件,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

5 个答案:

答案 0 :(得分:58)

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

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

由于扫描程序的分隔符是空格,而linePattern也是空格,因此缓冲区中可能有linePattern但没有可解析的标记。

通常,解析此问题的最常见方法是在解析文本每行中的所有标记(例如数字)后始终调用nextLine()。从Scanner读取用户输入时,如果使用System.in,则需要执行此操作。要使扫描程序超过此空白分隔符,必须使用scanner.nextLine()清除行分隔符。请参阅:Using scanner.nextLine()

<强>附录

LinePattern被定义为与此匹配的Pattern

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

答案 1 :(得分:15)

原因是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. 

答案 2 :(得分:14)

简短回答

文件末尾有一个空行。

空行的原因

如果你把你的内容保存到例如txt文件中,一些编辑会在你的文件中添加一个空的新行。

编辑以这种方式行事,因为这是POSIX标准的一部分:

  

3.206行

     

零个或多个非字符加上终止字符的序列。

本主题已在this thread中讨论过。

Java扫描程序文档

以下是Java 8 Scanner class的文档。

  

<强> hasNext()

     

如果此扫描器的输入中有另一个标记,则返回true。

  

<强> hasNextLine()

     

如果此扫描仪的输入中有另一行,则返回true。

Java代码行为的原因

由于上述事实,hasNextLine()将返回true,但hasNext()找不到任何内容,它可以识别为Token并返回false }。

有关其他信息,请参阅durron597发布。

答案 3 :(得分:5)

您正在使用next()的值,但要求hasNext()hasNextLine()。默认情况下,next()会将所有内容返回到下一个whitespace()。因此,您正在遍历所有空格分隔的字符串,并在每个字符串之后询问nextLine()

i 1 1 - &gt; hasNextLine()?真正。 hasNext()?也是如此。

1 1 - &gt; hasNextLine()?真正。 hasNext()?也是如此(仍然是空白)

1 - &gt; hasNextLine()?真(Line Seperator,可能)。 haxNext?错,再也没有空格。

答案 4 :(得分:0)

hasNext()和hasNextLine()的基本概念是

具有下一行:- 如果此扫描仪的输入中还有另一行,则返回true。  等待输入时,此方法可能会阻塞。扫描仪不会前进超过任何输入。

返回: 当且仅当此扫描仪具有另一行输入时,才返回true 抛出: IllegalStateException-如果此扫描仪已关闭

有下一步

如果下一个完整令牌与指定的模式匹配,则返回true。

完整的令牌由与定界符模式匹配的输入作为前缀和后缀。等待输入时,此方法可能会阻塞。扫描仪不会前进超过任何输入。

参数: pattern-要扫描的图案

返回: 当且仅当此扫描器具有与指定模式匹配的另一个令牌时,才为true

由于您的最后一个输入对nextLine()表示正确,因为对scan.nextLine()的调用;返回下一个标记。重要的是要注意,扫描程序会返回一个空格和一个字母,因为它是从最后一个令牌的末尾到下一行的开头进行读取。