【问题标题】:Can't understand how to solve noSuchElementException?不明白如何解决 noSuchElementException?
【发布时间】:2020-10-04 15:27:51
【问题描述】:

我正在尝试编写一个程序来读取一个名为 scores.txt 的文件,它会在该文件中打印出他们课程中平均成绩最高的学生的 ID 以及他们的学生 ID。

这是scores.txt 的样子:

34     c081 c082 c083 c084
S2023  99   75   85   62
S2025  -1   92   67   52
S1909  100  83   45   -1

所以基本上,34 的开头是学生数量的 3 和课程数量的 4(是的,我知道这很愚蠢,但文件是为我的任务提供的)。 c081等c数字是学校的课程代码,s2023等s数字是学号。中间的数字代表他们的分数,-1也表示他们没有被录取。

无论如何,到目前为止,我已经编写了一个 MySchool 类和一个 Student 类,我将它们粘贴在下面:

import java.io.File;
import java.io.FileNotFoundException; 
import java.util.ArrayList;
import java.util.Scanner; 

public class MySchool {
    public static void main(String[] args) {
        int numberOfStudents;
        ArrayList<Student> allStudents = new ArrayList<Student>() ;

        // grab first line only, and check if first target is integer, or string
        try {

            File scoresFile = new File("Scores.txt");
            Scanner scoresFileReader = new Scanner(scoresFile);

            String headerRow = scoresFileReader.nextLine();
            numberOfStudents = headerRow.charAt(0);

            while(scoresFileReader.hasNextLine()) {
            for (int studentI = 0; studentI < numberOfStudents; studentI++) {
                String studentText = scoresFileReader.nextLine();
                System.out.println(studentText);
                Student student = new Student(studentText);
                allStudents.add(student);
            }}

            scoresFileReader.close();

        } catch (FileNotFoundException e) {
            System.out.println("An error occurred");
            e.printStackTrace();
        }

        float highestAverage = 0;
        String highestScoringStudentNumber = null;

        for (Student student : allStudents) {
            if (student.getAverageScore() > highestAverage) {
                highestAverage = student.getAverageScore();
                highestScoringStudentNumber = student.getStudentNumber();
            }

        }
        System.out.println("Highest scoring student: " + highestScoringStudentNumber);
    }
}
import java.util.ArrayList;

public class Student {

    private String studentNumber;
    private ArrayList<Integer> scores = new ArrayList<Integer>();

    public Student(String studentText) {
        String[] parts = studentText.split(studentText, ' ');
        this.studentNumber = parts[0];

        for (int i = 1; i < parts.length - 1; i++) {
            scores.add(Integer.parseInt(parts[i + 1]));
        }
    }

    public String getStudentNumber() {
        return this.studentNumber;
    }

    public float getAverageScore() {
        int sum = 0;
        for (int i = 0; i <this.scores.size(); i++) {
            sum += this.scores.get(i);
        }
        return sum / this.scores.size();
    }


}

基本上,我希望能够为学生提供一个对象,其中有学生编号和分数。这样我就可以给他们一个平均值。

但是,我在读取文件时似乎做错了(以前从未这样做过),因为String studentText = scoresFileReader.nextLine(); 行向我抛出了一个错误,指出:Exception in thread "main" java.util.NoSuchElementException: No line found at java.base/java.util.Scanner.nextLine(Scanner.java:1651) at MySchool.main(MySchool.java:22)

如果有任何帮助,三个学生代码和他们的分数会在我收到此错误之前按应有的方式打印出来。

谁能帮我启动并运行它?不知道怎么解决

编辑:

我实际上已经注意到问题在于,当数据中没有 51 时,numberOfStudents 被设置为 51。即使我运行下面的代码,它也会打印headerRow 的第一个值,确认它是 3,这是正确的。当我使用相同的代码将它分配给numberOfStudents 时,它再次打印时突然变成了51?

import java.io.File; // Import the File class
import java.io.FileNotFoundException; // Import this class to handle errors
import java.util.ArrayList;
import java.util.Scanner; // Import the Scanner class to read text files

public class MySchool {
    public static void main(String[] args) {
        int numberOfStudents;
        ArrayList<Student> allStudents = new ArrayList<Student>() ;

        // grab first line only, and check if first target is integer, or string
        try {

            File scoresFile = new File("Scores.txt");
            Scanner scoresFileReader = new Scanner(scoresFile);


            String headerRow = scoresFileReader.nextLine();

            System.out.println(headerRow.charAt(0));

            numberOfStudents = headerRow.charAt(0);

            System.out.println(numberOfStudents);


            for (int studentI = 0; studentI < numberOfStudents; studentI++) {
                String studentText = scoresFileReader.nextLine();
                System.out.println(studentText);
                Student student = new Student(studentText);
                allStudents.add(student);
            }

            scoresFileReader.close();

        } catch (FileNotFoundException e) {
            System.out.println("An error occurred");
            e.printStackTrace();
        }

        float highestAverage = 0;
        String highestScoringStudentNumber = null;

        for (Student student : allStudents) {
            if (student.getAverageScore() > highestAverage) {
                highestAverage = student.getAverageScore();
                highestScoringStudentNumber = student.getStudentNumber();
            }

        }
        System.out.println("Highest scoring student: " + highestScoringStudentNumber);
    }
}

【问题讨论】:

  • 一个简短的调试会话将揭示问题所在。 while 循环内的 for 循环对我来说似乎不合适。这是一个或另一个。你应该检查numberOfStudents 的实际值是多少——如果它是你所期望的。
  • 其实很好!我刚刚看了看,numberOfStudents 的值似乎是 51。考虑到它根本不在数据中,我似乎无法弄清楚这个值是从哪里来的,更不用说第一个了特点?现在我比以前更难过了,有什么想法吗?
  • 尝试应用一些软件设计:通过分别读取标题、读取一行数据、解析一行数据的方法来分解问题。为每个方法编写单元测试并分别测试。

标签: java text-files file-handling nosuchelementexception


【解决方案1】:

问题在于您实际上是在读取字符的 ASCII 码,而不是值本身 - '3' == 51。您需要将字符转换为正确的值。最简单的方法是使用Character.getNumericValue(),例如:

char c = headerRow.charAt(0);
numberOfStudents = Character.getNumericValue(c);  

【讨论】:

  • 哦,当然,这是有道理的。我想事后看来,它返回的值不止一个字符也很奇怪!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-04
  • 2021-06-21
  • 2020-09-25
  • 2020-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多