Index was outside the bounds of the array?

橙三吉。 提交于 2019-12-13 09:49:21

问题


I keep getting this message "System.IndexOutOfRangeException: Index was outside the bounds of the array." when attempting to run a program I built, that utilized an exception catcher.

class StudentS { private List theStudentList;

    public bool PopulateStudents(string path)
    {
        theStudentList = new List<Student>();
        bool flag = false;
        try
        {
            List<string[]> strArrayList = new List<string[]>();
            using (StreamReader streamReader = new StreamReader(path))
            {
                string str;
                while ((str = streamReader.ReadLine()) != null)
                {
                    string[] strArray = str.Split(',');
                    strArrayList.Add(strArray);
                }
            }
            for (int index1 = 0; index1 < strArrayList.Count; ++index1)
            {
                string[] strArray = strArrayList[index1];
                Student student = new Student(strArray[0], strArray[1], strArray[2]); **where the error is**
                int index2 = 3;
                while (index2 < strArray.Length)
                {
                    student.EnterGrade(int.Parse(strArray[index2]), int.Parse(strArray[index2 + 1]));
                    index2 += 2;
                }
                student.CalGrade();
                theStudentList.Add(student);
            }
        }
        catch (Exception e)
        {
            flag = true;
            Console.WriteLine(e);
        }
        return flag;
    }

    public int ListLength
    {
        get
        {
            return theStudentList.Count;
        }
    }

    public float StudentAverage(int index)
    {
        return theStudentList.ElementAt(index).Average;
    }

    public string StudentGrade(int index)
    {
        return theStudentList.ElementAt(index).LetterGrade;
    }

    public string StudentID(int index)
    {
        return theStudentList.ElementAt(index).ID;
    }

    public string StudentLastName(int index)
    {
        return theStudentList.ElementAt(index).NameLast;
    }
}

class Student
{
    private float average;
    private ArrayList Earned;
    private string letterGrade;
    private string nameFirst;
    private string nameLast;
    private ArrayList Possible;
    private string studentID;

    public Student(string id)
    {
        studentID = null;
        nameFirst = null;
        nameLast = null;
        Earned = new ArrayList();
        Possible = new ArrayList();
    }

    public Student(string id, string first)
    {
        studentID = id;
        nameFirst = null;
        nameLast = null;
        Earned = new ArrayList();
        Possible = new ArrayList();
    }

    public Student(string id, string first, string last)
    {
        nameFirst = first;
        nameLast = last;
        studentID = id;
        Earned = new ArrayList();
        Possible = new ArrayList();
    }

    public float Average
    {
        get
        {
            return average;
        }
    }

    public string ID
    {
        get
        {
            return studentID;
        }
    }

    public string LetterGrade
    {
        get
        {
            return letterGrade;
        }
    }

    public string NameFirst
    {
        get
        {
            return nameFirst;
        }
        set
        {
            nameFirst = value;
        }
    }

    public string NameLast
    {
        get
        {
            return nameLast;
        }
        set
        {
            nameLast = value;
        }
    }

    public void CalGrade()
    {
        int num1 = 0;
        int num2 = 0;
        foreach (int num3 in Earned)
            num1 += num3;
        foreach (int num3 in Possible)
            num2 += num3;
        average = num1 / (float)num2;
        average = (float)Math.Round(average, 2);
        if (average >= 0.9)
            letterGrade = "A";
        if (average >= 0.8 && average < 0.9)
            letterGrade = "B";
        if (average >= 0.7 && average < 0.8)
            letterGrade = "C";
        if (average >= 0.6 && average < 0.7)
            letterGrade = "D";
        if (average >= 0.6)
            return;
        letterGrade = "U";
    }

    public void EnterGrade(int earnedValue, int possValue)
    {
        Earned.Add(earnedValue);
        Possible.Add(possValue);
    }
}

I am unsure as to what I have done wrong. Thanks for any help!

Edit: I went ahead and added a majority of the code here, in hopes that this answers your questions better. The data set I am dealing with is 4 rows, that are grabbed into the student array.


回答1:


index2 + 1 may be out of range in the expression strArray[index2 + 1] below:

while (index2 < strArray.Length)
{
    student.EnterGrade(int.Parse(strArray[index2]), int.Parse(strArray[index2 + 1]));
    index2 += 2;
}

To process two elements at a time, use index2 < strArray.Length - 1




回答2:


You may have a problem if the file from your path has an empty row as last row. You access strArray[0], strArray[1], strArray[2] no matter if it is an empty array or not.




回答3:


Maybe you are missing an Array.resize(). // This worked for me

Array.Resize<string[]>(ref strArrayList , count+ 1); // Count is the current length of strArrayList



回答4:


Flagged the two spots where you could run into trouble:

public bool PopulateStudents(string path)
{
    theStudentList = new List<Student>();
    bool flag = false;
    try
    {
        List<string[]> strArrayList = new List<string[]>();
        using (StreamReader streamReader = new StreamReader(path))
        {
            string str;
            while ((str = streamReader.ReadLine()) != null)
            {
                string[] strArray = str.Split(',');
                strArrayList.Add(strArray);
            }
        }
        for (int index1 = 0; index1 < strArrayList.Count; ++index1)
        {
            string[] strArray = strArrayList[index1];
            // below that, what makes you believe strArray's length is >= 3 ?
            Student student = new Student(strArray[0], strArray[1], strArray[2]);
            int index2 = 3;
            while (index2 < strArray.Length)
            {
                // here index2 will be < strArray.Length, but index2+1 might be ==
                student.EnterGrade(int.Parse(strArray[index2]), int.Parse(strArray[index2 + 1]));
                index2 += 2;
            }
            student.CalGrade();
            theStudentList.Add(student);
        }
    }
    catch (Exception e)
    {
        flag = true;
        Console.WriteLine(e);
    }
    return flag;
}

Note that your while loop could be replaced with:

for(int index2 = 3; index2 < strArray.Length - 1; index2 += 2)
{
    student.EnterGrade(...);
}



回答5:


This is difficult to diagnose because you provided limited information. If I could see the file you are running through your program, fed in as path, I would be able to compare what the function is attempting to do to the data it is trying to do it on. That said, this looks familiar to me so I will give solving it a try and at least give you a tool to try on it.

I experienced a similar issue with a program that needed to read a CSV file for a graphics program. The problem was that when the CSV file was created, an empty line was left at the end. This left me with an empty array to represent the last line in the file.

Also, have you verified that the arrays that are added to strArrayList are consistently sized?

If you check for this empty line at the end of your file and it does not exist and if you check for commas left at the end of the lines in your file passed in as path then you can try the edits I made above to get an idea of which line(s) in your CSV file is causing the problem. I commented all the edits I made with “EDIT:” so they would be easy to find. Without more information, I cannot fix the problem, but I can maybe help you look in the right direction.

The edited code with the output for line numbers in your file which are associated with errors is below. Good luck!

    public bool PopulateStudents(string path)
{
    theStudentList = new List<Student>();
    bool flag = false; 

    // EDIT: NEW VARIABLE int lineCounter declared and initialized before try block so it remains in scope when the catch block is called
    int counter = 0;

    try
    {
        List<string[]> strArrayList = new List<string[]>();
        using (StreamReader streamReader = new StreamReader(path))
        {
            string str;
            while ((str = streamReader.ReadLine()) != null)
            {
                string[] strArray = str.Split(',');
                strArrayList.Add(strArray);
            }
        }

        for (int index1 = 0; index1 < strArrayList.Count; ++index1)
        {
            // EDIT: UPDATE lineCounter
            ++lineCounter;

            string[] strArray = strArrayList[index1];
            Student student = new Student(strArray[0], strArray[1], strArray[2]);
            int index2 = 3;
            while (index2 < strArray.Length)
            {
                student.EnterGrade(int.Parse(strArray[index2]), int.Parse(strArray[index2 + 1]));
                index2 += 2;
            }
            student.CalGrade();
            theStudentList.Add(student);
        }
    }
    catch (Exception e)
    {
        flag = true;
        Console.WriteLine(e);

        // EDIT: PRINT CURRENT LINE
        Console.WriteLine(“error at line in file = “ + lineCounter);
    }
    return flag;
}


来源:https://stackoverflow.com/questions/50364778/index-was-outside-the-bounds-of-the-array

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!