【问题标题】:Index was outside the bounds of the array. But the index is in bounds [duplicate]指数数组的边界之外。但索引在界限内[重复]
【发布时间】:2014-11-08 07:03:01
【问题描述】:

我在一个项目中遇到异常“System.IndexOutOfRangeException”,并在此处隔离到此示例代码块中。

using System;

public class Program
{
    public static void Main()
    {
        string testStr = "AB5, BC4, CD8, DC8, DE6, AD5, CE2, EB3, AE7";
        //split testStr into substrings representing each edge
        string [] edges = testStr.Split(", ".ToCharArray());

        foreach(string edge in edges)
        {
            Console.Write(edge + "\n");
            char [] cEdge = edge.ToCharArray();
            char cost = cEdge[cEdge.Length - 1]; // what out of bounds?
            Console.Write(cost);
        }
    }
}

这个问题来自“char cost = cEdge[cEdge.Length - 1];”这一行。这对我来说毫无意义,因为此时 cEdge 应该是一个长度为 3 的数组。所以在 cEdge.Length - 1 处的索引应该是 2 的索引并且在数组的范围内。我很困惑,也许我看过一些东西。感谢您的时间和帮助。

【问题讨论】:

  • 如果 cEdge 的长度为零,那么cEdge[cEdge.Length-1] 将生成越界异常。

标签: c# arrays indexing bounds


【解决方案1】:

默认情况下,Split 方法在数组中包含空字符串。所以你 cEdge 数组的大小为 17,其中大约 8 个元素是空字符串。因此,当您尝试遍历数组时,空字符串的长度为 0,您尝试减去 1,这会使您超出数组的范围。

这里有几个选项。您可以放置​​ if 语句以确保 cEdge 的长度为 3 个字符,或者更新 Split 方法以使用将自动删除这些空元素的重载之一。

这里是你将如何使用重载:

string[] edges = testStr.Split(", ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

编辑

刚刚意识到我并没有真正解释为什么你会得到额外的空组。出现空元素是因为您为 split 函数提供了一个分隔符数组。然后,该函数使用数组匹配任何一个分隔符并将其分解为唯一元素。在你的情况下,有一个完美的例子,这会有所作为。如果您的源字符串testStr 在其中一个字段中包含一个空格,它实际上会将该字段分成两半,因为您在分隔符列表中提供了一个空格。

正如MSDN article 所说:

分隔符的每个元素定义一个单独的分隔符。如果两个分隔符相邻,或者在该实例的开头或结尾找到分隔符,则对应的数组元素包含 Empty。

例如:

string testStr = "AB5, BC4, CD8 Test, DC8";
string [] edges = testStr.Split(", ".ToCharArray());

在这种情况下,大多数人认为我们最终会得到一个看起来像这样的数组:

+----------------------------+
| AB5 | BC4 | CD8 Test | DC8 |
+----------------------------+

但是这个方法的实际输出会更像这样:

+------------------------------+
| AB5 | BC4 | CD8 | Test | DC8 |
+------------------------------+

要每次都获得所需的输出,更强大的解决方案应如下所示:

String[] edges = Regex.Split(testStr, Regex.Escape(", "), RegexOptions.None);

如果拆分恰好在一个紧密循环中,您可能需要考虑在进入循环之前编译正则表达式,但这是一个不同的问题。

【讨论】:

    【解决方案2】:

    问题是当数组为空时,Length 属性将等于 0,而 cEdge[0 - 1] 最终会给你IndexOutOfRangeException。考虑在索引数组之前检查Length

    using System;
    
    public class Program
    {
        public static void Main()
        {
            string testStr = "AB5, BC4, CD8, DC8, DE6, AD5, CE2, EB3, AE7";
            //split testStr into substrings representing each edge
            string [] edges = testStr.Split(", ".ToCharArray());
    
            foreach(string edge in edges)
            {
                Console.Write(edge + "\n");
                char [] cEdge = edge.ToCharArray();
                if (cEdge.Length > 0)
                {
                    char cost = cEdge[cEdge.Length - 1]; // what out of bounds?
                    Console.Write(cost);
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      因为第2、4、6等...边的数组值为空。

      static void Main(string[] args)
          {
              string testStr = "AB5, BC4, CD8, DC8, DE6, AD5, CE2, EB3, AE7";
              //split testStr into substrings representing each edge
              string[] edges = testStr.Split(", ".ToCharArray());
              char[] cEdge;
              foreach (string edge in edges)
              {
                  Console.Write(edge + "\n");
                  cEdge = edge.ToCharArray();
                  char cost = new char();
                  if(cEdge.Length > 0)
                  { 
                      cost = cEdge[0]; // what out of bounds?
                  }
                  Console.Write(cost);
              }
              Console.Read();
          }
      

      【讨论】:

        【解决方案4】:

        我跟踪您的代码,我发现边缘值包含 "" 导致 cEdge.Length 为 0 你必须像这样修复你的代码:

        public static void Main()
                {
                    string testStr = "AB5, BC4, CD8, DC8, DE6, AD5, CE2, EB3, AE7";
                    //split testStr into substrings representing each edge
                    string[] temp = { ", " };
                    string[] edges = testStr.Split(temp, StringSplitOptions.RemoveEmptyEntries);
        
                    foreach (string edge in edges)
                    {
                        Console.Write(edge + "\n");
                        char[] cEdge = edge.ToCharArray();
                        char cost = cEdge[cEdge.Length - 1]; // what out of bounds?
                        Console.Write(cost);
                    }
                }
        

        【讨论】:

          【解决方案5】:

          您通过 ',' 和 ' ' 的 char 数组拆分字符串
          你会得到类似的东西:
          ["AB5","","BC4","", ....]
          看这里http://msdn.microsoft.com/en-us/library/b873y76a(v=vs.110).aspx
          在这一行比边缘 == ""
          字符成本 = cEdge[cEdge.Length - 1];
          cEdge.Length == 0
          你得到 System.IndexOutOfRangeException 您应该使用以下语法
          testStr.Split(", ".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);

          【讨论】:

            猜你喜欢
            • 2021-08-12
            • 2011-04-15
            • 2018-10-26
            相关资源
            最近更新 更多