索引超出了数组的界限.但该指数是有界的



我在一个项目上遇到了异常"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的索引,并且在数组的范围内。我很困惑,也许我看得太多了。谢谢你的时间和帮助。

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

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

以下是如何使用过载:

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

编辑

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

正如MSDN文章所说:

分隔符的每个元素都定义了一个单独的分隔符。如果两个分隔符相邻,或者在该实例的开头或结尾找到一个分隔符,则相应的数组元素包含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);

如果拆分恰好在一个紧密的循环中,您可能需要考虑在进入循环之前编译regex,但这是另一个问题。

问题是当数组为空时,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);
            }
        }
    }
}

因为第二、第四、第六等等。。。边的数组值为空。

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

我跟踪您的代码,发现边值包含导致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);
            }
        }

通过'、'和'的字符数组拆分字符串
你会得到这样的东西:
["AB5"、"、"BC4"、"……]
看这里http://msdn.microsoft.com/en-us/library/b873y76a(v=vs.110).aspx
在此行中,超过edge="
char cost=cEdge[cEdge.Length-1]
cEdge.Length==0
然后得到System.IndexOutOfRangeException您应该使用以下语法
testStr.Split(",".ToCharArray(),StringSplitOptions.RemoveEmptyEntries);

最新更新