简体   繁体   English

Java-并行数组上的ArrayIndexOutOfBounds错误

[英]Java - ArrayIndexOutOfBounds Error on parallel arrays

I'm having a bit of trouble with this project: 我在这个项目上遇到了麻烦:

We're given a text file of 5 students, with 4 number grades following each name in a separate line. 我们给了一个文本文件,其中有5个学生,每个名字后面有4个数字等级。 We have to use our main method to read the file, then perform calculations in the gradebook class. 我们必须使用main方法读取文件,然后在成绩簿类中执行计算。 However, from what others in class have been saying the method we're using is archaic at best, involving Parallel arrays. 但是,在课堂上其他人一直在说,我们正在使用的方法充其量只是过时的,涉及并行数组。 We don't really seem to have any other option though, so I'm making due with what I can. 我们似乎还没有其他选择,所以我尽我所能。 But near what I'm hoping is the end of this code, I've encountered a problem, where it says the index that contains the grades for students is out of bounds. 但是,我希望这段代码快要结束了,我遇到了一个问题,它说包含学生成绩的索引超出范围。

I've rewritten the readFile method in my main in quite a few different ways, but no matter what I still get these errors. 我已经以多种不同的方式在我的main中重写了readFile方法,但是无论我仍然得到这些错误是什么。 Could anyone help me understand what's going on? 谁能帮助我了解发生了什么事? I'll post everything I can. 我会尽力而为。 I also apologize if I'm a bit slow/incapable with this, this is my first time coding java in months unfortunately. 如果对此我有点慢/无能为力,我也表示歉意,不幸的是,这是我几个月来第一次编写Java。

Also, in the error I post, line 64 of the main class is: grades[test] = inputFile.nextDouble(); 另外,在我发布的错误中,主类的第64行是:grades [test] = inputFile.nextDouble();

run:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
    at Package1.GradeBookDemo.readFile(GradeBookDemo.java:64)
    at Package1.GradeBookDemo.main(GradeBookDemo.java:29)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)

The following is my Main method: 以下是我的主要方法:

import java.util.Scanner;
import java.io.*;

public class GradeBookDemo {

    public static void main(String[] args) throws IOException {

        // Create a new gradebook object
        Gradebook gradeBook = new Gradebook();

        //Read StudentInfo file for names and test scores using readFile method
        readFile(gradeBook);

        //Output Student data
        for (int index = 1; index <= 5; index++)
        {
            System.out.println("Name: " + gradeBook.getName(index) + 
                    "\tAverage Score: " + gradeBook.getAverage(index) +
                    "\tGrade: " + gradeBook.getLetterGrade(index));
        }

    }


    // This method reads from the StudentInfo file
    public static void readFile(Gradebook gradeBook) throws IOException
    {

        int nI = 0; // Name index
        int gI = 4; // Grade index

        // Create a string array to hold student names and another for grades
        double[] grades = new double[gI];

        // Access the StudentInfo text file
        File sFile = new File("StudentInfo.txt");
        // Create a scanner object to read the file
        Scanner inputFile = new Scanner(sFile);

        // Read StudentInfo
        for(int student = 1; student <= 5; student++)
        {
            String name = inputFile.nextLine();
            gradeBook.setName(student, name);
            for (int test = 0; test < 4; test++)
            {
                grades[test] = inputFile.nextDouble();
            }
        }

    // Close the file
    inputFile.close();

    }

}

And then the Gradebook class 然后是成绩簿课

public class Gradebook {

    // Declare fields
    private final int NUM_STUDENTS = 5;
    private final int NUM_TESTS = 4;
    // ArrayList for names of students - 5 in total
    private String[] names = new String[NUM_STUDENTS];
    // Array to store letter grades
    private char[] grades;
    // array to store each student's scores
    private double[] scores1 = new double[NUM_TESTS];
    private double[] scores2 = new double[NUM_TESTS];
    private double[] scores3 = new double[NUM_TESTS];
    private double[] scores4 = new double[NUM_TESTS];
    private double[] scores5 = new double[NUM_TESTS];


    // Method to set student's name
    public void setName(int studentNumber, String name)
    {
        names[studentNumber-1] = name;
    }

    // Method sets student scores

    public void setScores(int studentNumber, double[] scores)
    {
    switch(studentNumber)
        {
            case 1:copyArray(scores1,scores); break;
            case 2:copyArray(scores2,scores); break;
            case 3:copyArray(scores3,scores); break;
            case 4:copyArray(scores4,scores); break;
            case 5:copyArray(scores5,scores); break;
            default:break;
        }
    }

    // Returns the student's name

    public String getName(int studentNumber)
    {
    return names[studentNumber-1];
    }

    // Returns student's average score

    public double getAverage(int studentNumber)
    {
    double avg=0.0;
    switch(studentNumber)
    {
        case 1:avg = calcAverage(scores1); break;
        case 2:avg = calcAverage(scores2); break;
        case 3:avg = calcAverage(scores3); break;
        case 4:avg = calcAverage(scores4); break;
        case 5:avg = calcAverage(scores5); break;
        default:break;
    }
    return avg;
    }

    // Returns the student's letter grade

    public char getLetterGrade(int studentNumber)
    {
    char lettergrade;
    if(getAverage(studentNumber)>=90 && getAverage(studentNumber)<=100)
            lettergrade = 'A';
    else if(getAverage(studentNumber)>=80 && getAverage(studentNumber)<=89)
        lettergrade = 'B';
    else if(getAverage(studentNumber)>=70 && getAverage(studentNumber)<=79)
        lettergrade = 'C';
    else if(getAverage(studentNumber)>=60 && getAverage(studentNumber)<=69)
        lettergrade = 'D';
    else
            lettergrade = 'F';
    return lettergrade;

    }

    // Calculates the student's average

    private double calcAverage(double[] scores)
    {
    double sum=0;
    for(int i=0; i<scores.length; i++)
            sum+=scores[i];
    return sum/scores.length;

    }

    // Determines student's letter grade based on average score

    public char LetterGrade(double average)
    {
    char lettergrade;
    if(average>=90 && average<=100)
        lettergrade = 'A';
    else if(average>=80 && average<=89)
        lettergrade = 'B';
    else if(average>=70 && average<=79)
        lettergrade = 'C';
    else if(average>=60 && average<=69)
        lettergrade = 'D';
    else
            lettergrade = 'F';
    return lettergrade;
    }

    // Array copy method
    private void copyArray(double[] to, double[] from)
    {
    System.arraycopy(from, 0, to, 0, from.length);
    }


}

Here is the file the program is reading - StudentInfo.txt: 这是程序正在读取的文件-StudentInfo.txt:

Joanne Smith
98
89
100
76
Will Jones
67
89
91
88
Kerry McDonald
78
79
88
91
Sam Young
88
98
76
56
Jill Barnes
94
93
91
98

You will get InputMismatchException 您将获得InputMismatchException

Reason 原因
String name = inputFile.nextLine(); 字符串名称= inputFile.nextLine(); //Reads the current line, Scanner moves to next line //读取当前行,扫描仪移至下一行
grades[test] = inputFile.nextDouble(); 成绩[测试] = inputFile.nextDouble(); //Reads the next double value //读取下一个double值

You should be able to read first student name and grades without any issues. 您应该能够轻松阅读第一名学生的姓名和年级。 After reading 76, the scanner position is at the end of line 5. It didn't skip line 5. 读取76后,扫描仪位置在第5行的末尾。它没有跳过第5行。

So, when you try to read next student name by calling nextLine(). 因此,当您尝试通过调用nextLine()读取下一个学生姓名时。 you will see "". 你会看见 ””。 and scanner moves to line 6. 扫描仪移至第6行。

So the next call to nextDouble() fails. 因此,对nextDouble()的下一次调用失败。

Quick fix 快速解决
use Double.parseDouble(inputFile.nextLine()); 使用Double.parseDouble(inputFile.nextLine()); for reading the double values here 在这里读取双精度值

This is a rather interesting "This can not happen" scenario. 这是一个非常有趣的“这不可能发生”的情况。 From the comments I would guess that the code actually compiled has an error in the inner for-loop. 从注释中,我猜想实际编译的代码在内部for循环中有错误。 You need to find which file you are actually compiling. 您需要找到实际正在编译的文件。

Try adding random 尝试添加随机

System.out.println("Got HERE!");

to your code and see if any of them are actually printed. 到您的代码,看看是否有任何实际打印。 Because the code you show should not be able to give that exception. 因为您显示的代码不应提供该异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM