Индекс находился вне границ массива?

Я все время получаю это сообщение «System.IndexOutOfRangeException: индекс вышел за пределы массива». при попытке запустить созданную мной программу, в которой используется ловушка исключений.

класс StudentS { частный список 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);
    }
}

Я не уверен, что сделал не так. Спасибо за любую помощь!

Обновлено: я пошел дальше и добавил сюда большую часть кода в надежде, что это лучше ответит на ваши вопросы. Набор данных, с которым я имею дело, состоит из 4 строк, которые помещаются в массив студентов.

Ну и дела, интересно, был ли индекс, который я передал моей ошибке, действителен и не выходит за рамки? Смотрите на это как на точную копию вопроса.

Neijwiert 16.05.2018 09:31

Возможный дубликат Что такое IndexOutOfRangeException / ArgumentOutOfRangeException и как его исправить?

Tetsuya Yamamoto 16.05.2018 09:37

Укажите нам строку, которая вызывает исключение, значение используемого индекса и Length массива, к которому осуществляется доступ.

mjwills 16.05.2018 09:50

Студент студент = новый студент (strArray [0], strArray [1], strArray [2]) ;. Длина массива, к которому я пытаюсь получить доступ, будет 4.

Toby Z 16.05.2018 10:41

@TobyZ: когда выбрасывается исключение IndexOutOfRangeException - может показаться, что длина НЕ равна 4. Поместите условную точку останова на этой строке (strArray.Length! = 4)

PaulF 16.05.2018 10:54
will be 4 Для ясности, я не спрашиваю вас, что это за считать. Я прошу вас на самом деле проверятьLength, когда возникает исключение.
mjwills 16.05.2018 13:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
6
915
5

Ответы 5

index2 + 1 может быть вне диапазона приведенного ниже выражения strArray[index2 + 1]:

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

Для одновременной обработки двух элементов используйте index2 < strArray.Length - 1

Возможно, вам не хватает Array.resize (). // Это сработало для меня

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

Отметил два места, где могут возникнуть проблемы:

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;
}

Обратите внимание, что ваш цикл while можно заменить на:

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

У вас может возникнуть проблема, если файл с вашего path имеет пустую строку в качестве последней строки. Вы получаете доступ к strArray[0], strArray[1], strArray[2] независимо от того, пустой это массив или нет.

Забавно, я тоже указал на это 1 час назад в своем ответе, сказав, что strArray может иметь менее 3 значений, но сказать, что это может быть из-за пустой строки в конце файла, тоже ценно

Rafalon 16.05.2018 10:40

Это сложно диагностировать, потому что вы предоставили ограниченную информацию. Если бы я мог видеть файл, который вы запускаете в своей программе, введенный как путь, я мог бы сравнить, что функция пытается сделать, с данными, с которыми она пытается это сделать. Тем не менее, это кажется мне знакомым, поэтому я попробую решить эту проблему и, по крайней мере, дам вам инструмент, чтобы попробовать это.

У меня возникла аналогичная проблема с программой, которой необходимо было прочитать файл CSV для графической программы. Проблема заключалась в том, что при создании файла CSV в конце оставалась пустая строка. Это оставило меня с пустым массивом, представляющим последнюю строку в файле.

Кроме того, вы проверили, что массивы, добавленные в strArrayList, имеют одинаковый размер?

Если вы проверяете наличие этой пустой строки в конце вашего файла, а она не существует, и если вы проверяете наличие запятых, оставшихся в конце строк в вашем файле, переданных в качестве пути, вы можете попробовать изменения, которые я сделал выше, чтобы получить представление о том, какая строка (строки) в вашем CSV-файле вызывает проблему. Я прокомментировал все правки, которые я внес с помощью «Обновлено:», чтобы их было легко найти. Без дополнительной информации я не могу решить проблему, но, возможно, я могу помочь вам посмотреть в правильном направлении.

Отредактированный код с выводом номеров строк в вашем файле, связанных с ошибками, приведен ниже. Удачи!

    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;
}

Другие вопросы по теме