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

Why is hasNext() False, but hasNextLine() is True?

提问人:DRich 提问时间:8/14/2015 最后编辑:John KugelmanDRich 更新时间:7/20/2018 访问量:22625

问:

问题

对于扫描器对象,方法返回 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
java.util.scanner

评论

24赞 Swagin9 8/14/2015
输入文件末尾是否有空行?
16赞 JB Nizet 8/14/2015
hasNextLine()如果有下一行,甚至为空,则返回 true。 如果还有一个标记,则返回 true。空行是不包含任何标记的行。hasNext()
1赞 aioobe 8/14/2015
我认为不消耗 ,所以“光标”就在换行符之前,因此有下一行,但没有更多的标记。next\n
0赞 DRich 8/14/2015
感谢您的回复。该文件在“i 1 1”后面不包含空行,因此我希望一旦它移动最后一行的第二个“1”,就不会再有一行或返回字符可供它拾取。有趣的是,如果我在循环后使用 nextLine() 方法,我不会收到错误。所以也许那里挂着一个回归角色?关于如何获取 hasNextLine() 方法和 hasNext() 方法的结果以对齐的任何想法?

答:

5赞 Florian Schaetz 8/14/2015 #1

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

i 1 1 -> hasNextLine()?真。?也是真的。hasNext()

1 1 -> hasNextLine()?真。?也是正确的(仍然有一个空格)hasNext()

1 -> hasNextLine()?True(可能是行分隔符)。hax下一个?False,不再有空格。

16赞 Daniel Centore 8/14/2015 #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. 
59赞 durron597 8/14/2015 #3

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

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

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

通常,处理此问题的最常见方法是始终在解析文本每行中的所有标记(例如数字)后调用。在使用 时,也需要从 中读取用户的输入时执行此操作。若要使扫描程序超过此空格分隔符,必须用于清除行分隔符。请参见: 使用 scanner.nextLine()nextLine()ScannerSystem.inscanner.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}+");

评论

0赞 DRich 8/14/2015
首先,感谢您的详细回复。所以我明白,如果没有另一个令牌存在,可能会有一个Line_Separator_Pattern。但是,在文件中,我无法将光标推进到最后的“1”之外。是否有一些我无法通过 gedit 删除的空格字符?
0赞 Bernhard Barker 8/14/2015
"You have a single extra newline at the end of your file."- 我认为它比这更普遍,例如 - 文件末尾有任何数量的空格(或您指定的任何分隔符)。
0赞 durron597 8/14/2015
@Dukeling是的,但 OP 说他在某处检查了他的文件,它没有多余的空白
14赞 kamwo 8/14/2015 #4

简答

文件末尾有一个空行。


空行的原因

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

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

3.206线

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

此主题已在此线程中讨论。


Java Scanner 文档

以下是 Java 8 Scanner 类的文档。

hasNext()

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


hasNextLine()

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


Java 代码行为的原因

由于上述事实,将返回,但找不到任何东西,它可以识别并因此返回。hasNextLine()truehasNext()Tokenfalse

有关其他信息,请参阅 durron597 帖子。

0赞 Manpreet gujral 7/20/2018 #5

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

hasNextLine:- 如果此扫描程序的输入中有另一行,则返回 true。此方法可能会在等待输入时阻塞。扫描仪不会前进到任何输入。

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

has下一页

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

完整标记的前缀和后缀由与分隔符模式匹配的输入。此方法可能会在等待输入时阻塞。扫描仪不会前进到任何输入。

参数: pattern - 要扫描的模式

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

由于您上次输入对 nextLine() 说 true,因为对 scan.nextLine() 的调用;返回下一个令牌。请务必注意,扫描程序返回一个空格和一个字母,因为它从最后一个标记的末尾读取到下一行的开头。