一段时间内的多个input.next()(input.hasNext())会触发Java中的NoTouchElementException

一段时间内的多个input.next()(input.hasNext())会触发Java中的NoTouchElementException,java,file,input,Java,File,Input,我有一个文本文件 Jim,A,94 Pam,B-4,120 Michael,CC,3 我想将每个由逗号分隔的标记保存到字符串变量中。我有以下代码: File f = new File(filename); Scanner input = new Scanner(f); input.useDelimiter(","); while (input.hasNext()) { String s1 = input.next(); String s2 = input.

我有一个文本文件

Jim,A,94
Pam,B-4,120
Michael,CC,3
我想将每个由逗号分隔的标记保存到字符串变量中。我有以下代码:

File f = new File(filename);
Scanner input = new Scanner(f);
input.useDelimiter(",");

while (input.hasNext())
{
    String s1 = input.next();
    String s2 = input.next();
    String s3 = input.next();
}

input.close();

但这不断引发非接触性异常。我做错了什么?

这里有另一种方法来实现你想要做的事情:

File f = new File(filename);
Scanner input = new Scanner(f);

while (input.hasNext()) {
    String[] sarray = input.nextLine().split(",");
    for (String s : sarray ) {
        System.out.println(s);
    }
}

当然,这是可以改进的,但基本上我建议您使用扫描仪逐行读取文件,然后使用逗号分隔符进行拆分。

下面是另一种实现您尝试执行的操作的方法:

File f = new File(filename);
Scanner input = new Scanner(f);

while (input.hasNext()) {
    String[] sarray = input.nextLine().split(",");
    for (String s : sarray ) {
        System.out.println(s);
    }
}

当然,这是可以改进的,但基本上我建议您使用扫描仪逐行读取文件,然后按逗号分隔符拆分。

这是
扫描仪#next()
工作原理的一个微妙的怪癖。该方法查找“标记”,它是分隔符字符出现之间的所有内容。默认分隔符是
“\\p{javaWhitespace}+”
,其中包括
\n
\r

您已将分隔符更改为逗号,并且只更改了逗号。对于
扫描仪
而言,输入如下所示:

Jim,A,94\nPam,B-4,120\nMichael,CC,3
扫描仪看到的标记包括:

Jim
A
94\nPam
B-4
120\nMichael
CC
3
这只有7个令牌,因此在满足所有
next()
调用之前,您先到达输入的末尾

最简单的修复方法是将分隔符设置为
“[,”+System.lineSeparator()+“]”“


然而,
Scanner
是新开发人员无休止的错误和挫折的原因,应该被弃用和禁止(由于现有的代码库,这种情况不会发生)。你应该读整行,然后自己解析。

这是
Scanner\next()
如何工作的一个微妙的怪癖。该方法查找“标记”,它是分隔符字符出现之间的所有内容。默认分隔符是
“\\p{javaWhitespace}+”
,其中包括
\n
\r

您已将分隔符更改为逗号,并且只更改了逗号。对于
扫描仪
而言,输入如下所示:

Jim,A,94\nPam,B-4,120\nMichael,CC,3
扫描仪看到的标记包括:

Jim
A
94\nPam
B-4
120\nMichael
CC
3
这只有7个令牌,因此在满足所有
next()
调用之前,您先到达输入的末尾

最简单的修复方法是将分隔符设置为
“[,”+System.lineSeparator()+“]”“


然而,
Scanner
是新开发人员无休止的错误和挫折的原因,应该被弃用和禁止(由于现有的代码库,这种情况不会发生)。您应该做的是读取整行,然后自己解析它们。

您有一个自定义分隔符
。因此,您的输入字符串由
分隔,该字符前后的所有内容都将构成
.next()返回的标记

\n
转义字符,作为新行字符出现在输入中:

\n(linefeed LF,Unicode\u000a)


它被作为您令牌的一部分读取。

您有一个自定义分隔符
。因此,您的输入字符串由
分隔,该字符前后的所有内容都将构成
.next()返回的标记

\n
转义字符,作为新行字符出现在输入中:

\n(linefeed LF,Unicode\u000a)


它将作为您令牌的一部分被读取。

非常有效,谢谢!不客气!非常好用,谢谢!不客气!嘿,谢谢你。这是有道理的。我不知道useDelimiter只使用逗号。我将代码更改为
input.useDelimiter(“,|\\n”)成功了。完全同意你的观点@Jim GarrisonHey,谢谢。这是有道理的。我不知道useDelimiter只使用逗号。我将代码更改为
input.useDelimiter(“,|\\n”)成功了。完全同意你的观点@Jim Garrison