Java:NoSuchElementException

我开始只是在数据文件中读取练习。 当我运行程序时,数据文件被读取,什么不是,但由于某种原因,我仍然得到“NoSuchElementException”,我的输出没有按照它应该的方式格式化。 这是发生了什么:

我创建了一个简单的数据文件,如下所示:

Barry Burd Author 5000.00 Harriet Ritter Captain 7000.00 Ryan Christman CEO 10000.00 

之后我写了一个简单的“getter”和“setter”程序(代码如下)。

 import static java.lang.System.out; //This class defines what it means to be an employee public class Employee { private String name; private String jobTitle; public void setName(String nameIn) { name = nameIn; } public String getName() { return name; } public void setJobTitle(String jobTitleIn) { jobTitle = jobTitleIn; } public String getJobTitle() { return jobTitle; } /*The following method provides the method for writing a paycheck*/ public void cutCheck(double amountPaid) { out.printf("Pay to the order of %s ", name); out.printf("(%s) ***$", jobTitle); out.printf("%,.2f\n", amountPaid); } } 

很容易。 然后我编写了实际使用这些东西的程序(下面的代码)。

 import java.util.Scanner; import java.io.File; import java.io.IOException; public class DoPayroll { public static void main(String[] args) throws IOException { Scanner diskScanner = new Scanner(new File("EmployeeInfo.txt")); for (int empNum = 1; empNum <= 3; empNum++) { payOneEmployee(diskScanner); } } static void payOneEmployee(Scanner aScanner) { Employee anEmployee = new Employee(); anEmployee.setName(aScanner.nextLine()); anEmployee.setJobTitle(aScanner.nextLine()); anEmployee.cutCheck(aScanner.nextDouble()); aScanner.nextLine(); } } 

这是我的输出:

 Pay to the order of Exception in thread "main" java.util.NoSuchElementException: No line found at java.util.Scanner.nextLine(Scanner.java:1516) at DoPayroll.payOneEmployee(DoPayroll.java:25) at DoPayroll.main(DoPayroll.java:14) Barry Burd ( Author) ***$5,000.00 Pay to the order of Harriet Ritter ( Captain) ***$7,000.00 Pay to the order of Ryan Christman ( CEO) ***$10,000.00 

编辑我发现了问题,但我不明白它哈哈。 显然,我必须在数据文件的末尾添加一个空行….为什么?

我发现了问题,但我不明白它哈哈。 显然,我必须在数据文件的末尾添加一个空行….为什么?

因为您告诉Scanner在输入文件中的工资之后将有回车符。 但是,对于最后一个条目,没有回车符,因此它确定您发生了编程错误并抛出了未经检查的exception。

您可以像这样解决代码中的问题:

 static void payOneEmployee(Scanner aScanner) { Employee anEmployee = new Employee(); anEmployee.setName(aScanner.nextLine()); anEmployee.setJobTitle(aScanner.nextLine()); anEmployee.cutCheck(aScanner.nextDouble()); if (aScanner.hasNextLine()) { aScanner.nextLine(); } } 

每次调用aScanner.nextLine()时,最后都会调用aScanner.nextLine() 。 这包括你最后一次调用它(当你的for循环中empNum等于3时)。 当文件中没有更多新行( \n )并且你仍然调用nextLine() ,你收到NoSuchElementException因为……好吧……没有这样的元素。 这是因为文件中的最后一个元素是0字符。

为了在将来避免这种情况,您可以添加一个简单的检查器。 java.util.Scanner已经为您实现了hasNextLine() 。 因此,你可以简单地改变

 aScanner.nextLine(); 

… 至 …

 if(aScanner.hasNextLine()) aScanner.nextLine(); 

我认为它到达了文件的末尾。 你应该添加一个while循环:

 while(aScanner.hasNext()) { ... } 

这可以防止扫描程序超出文件末尾。

这里的问题是你的文件以字符“0”结束,而aScanner.nextLine()试图使用换行符(’\ n’)。

现在,这里有趣的是弹出exception的地方。 它似乎是在第一次cutCheck()打印的中间。 我的猜测是它与IO缓冲和输出流的异步性有关。 out.printf()是stdout,而错误消息是stderr,所以这可以解释那里的奇怪行为。

如果你在for循环中放入一个Thread.sleep() ,这可能会清除打印问题(虽然这显然只是一个好奇心,而不是修复你的代码或类似的东西)。

你应该在调用aScanner.nextLine()之前调用hasNextLine。 您正试图在文件末尾读取没有一行的行。