Я все время получаю это сообщение «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 строк, которые помещаются в массив студентов.
Возможный дубликат Что такое IndexOutOfRangeException / ArgumentOutOfRangeException и как его исправить?
Укажите нам строку, которая вызывает исключение, значение используемого индекса и Length массива, к которому осуществляется доступ.
Студент студент = новый студент (strArray [0], strArray [1], strArray [2]) ;. Длина массива, к которому я пытаюсь получить доступ, будет 4.
@TobyZ: когда выбрасывается исключение IndexOutOfRangeException - может показаться, что длина НЕ равна 4. Поместите условную точку останова на этой строке (strArray.Length! = 4)
will be 4 Для ясности, я не спрашиваю вас, что это за считать. Я прошу вас на самом деле проверятьLength, когда возникает исключение.





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 значений, но сказать, что это может быть из-за пустой строки в конце файла, тоже ценно
Это сложно диагностировать, потому что вы предоставили ограниченную информацию. Если бы я мог видеть файл, который вы запускаете в своей программе, введенный как путь, я мог бы сравнить, что функция пытается сделать, с данными, с которыми она пытается это сделать. Тем не менее, это кажется мне знакомым, поэтому я попробую решить эту проблему и, по крайней мере, дам вам инструмент, чтобы попробовать это.
У меня возникла аналогичная проблема с программой, которой необходимо было прочитать файл 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;
}
Ну и дела, интересно, был ли индекс, который я передал моей ошибке, действителен и не выходит за рамки? Смотрите на это как на точную копию вопроса.