【问题标题】:Index was outside the bounds of the array?指数数组的边界之外?
【发布时间】:2018-10-26 03:32:56
【问题描述】:

我不断收到此消息“System.IndexOutOfRangeException:索引超出了数组的范围。”在尝试运行我构建的程序时,该程序使用了异常捕获器。

班级学生 { 私人名单 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 行,它们被抓取到学生数组中。

【问题讨论】:

  • 哎呀,我想知道我传递给我的错误的索引是否有效并且没有超出范围?请参阅this 作为一个完全重复的问题。
  • 请指出引发异常的行、正在使用的索引的值以及正在访问的数组的Length
  • 学生 student = new Student(strArray[0], strArray[1], strArray[2]);.我尝试访问的数组长度为 4。
  • @TobyZ: 抛出 IndexOutOfRangeException - 长度似乎不是 4。在该行上放置一个条件断点 (strArray.Length != 4)

标签: c# arrays exception try-catch


【解决方案1】:

这很难诊断,因为您提供的信息有限。如果我可以看到您正在通过您的程序运行的文件,作为路径输入,我将能够将函数尝试执行的操作与它尝试执行的数据进行比较。也就是说,这对我来说看起来很熟悉,所以我会尝试解决它,至少给你一个工具来尝试它。

我遇到了一个类似的问题,该程序需要为图形程序读取 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;
}

【讨论】:

    【解决方案2】:

    如果来自path 的文件的最后一行有一个空行,您可能会遇到问题。 你访问strArray[0], strArray[1], strArray[2]不管它是否是一个空数组。

    【讨论】:

    • 有趣的是,我在 1 小时前的回答中也指出了这一点,说 strArray 的值可能少于 3 个,但说这可能是由于文件末尾的空行很有价值太
    【解决方案3】:

    标出了可能遇到麻烦的两个地方:

    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(...);
    }
    

    【讨论】:

      【解决方案4】:

      也许您缺少 Array.resize()。 // 这对我有用

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

      【讨论】:

        【解决方案5】:

        index2 + 1 可能超出以下表达式 strArray[index2 + 1] 的范围:

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

        要一次处理两个元素,请使用index2 &lt; strArray.Length - 1

        【讨论】:

          猜你喜欢
          • 2011-04-15
          • 1970-01-01
          • 2014-06-05
          相关资源
          最近更新 更多