2

我开始通过简单地读取数据文件来做练习。当我运行程序时,数据文件被读取,但由于某种原因,我仍然得到“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

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

4

5 回答 5

2

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

因为您告诉Scanner输入文件中的薪水后会有回车。但是,对于最后一个条目,没有回车,因此它确定您犯了编程错误并引发了未经检查的异常。

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

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();
    }
}
于 2012-07-18T19:48:47.010 回答
2

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

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

aScanner.nextLine();

... 到 ...

if(aScanner.hasNextLine()) aScanner.nextLine();
于 2012-07-18T19:51:04.917 回答
1

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

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

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

于 2012-07-18T19:47:33.080 回答
0

这里的问题是您的文件以字符“0”结尾,同时aScanner.nextLine()尝试使用换行符(“\n”)。

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

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

于 2012-07-18T19:47:40.537 回答
0

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

于 2012-07-18T19:49:24.030 回答