2014-11-08 71 views
-1

我遇到了一个项目异常“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,并且位于数组的边界内。我很困惑,也许我已经看过一些东西。感谢您的时间和帮助。

+0

如果cEdge的长度为零,那么'cEdge [cEdge.Length-1]'将产生一个越界异常。 – dbc 2014-11-08 07:10:10

回答

1

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

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

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

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

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

编辑

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

作为MSDN article所说:

分离器中的每个元素定义了单独的分隔符。如果两个分隔符相邻,或者在此实例的开头或结尾处找到分隔符,则相应的数组元素将包含空白。

因此,例如:

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

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

0

因为第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(); 
    } 
0

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

您的开裂的字符数组的字符串“”以及'
和你喜欢的东西:
[ “AB5”, “”, “BC4”, “”,...]
看这里http://msdn.microsoft.com/en-us/library/b873y76a(v=vs.110).aspx
在这一行比边==“”
char cost = cEdge [cEdge.Length - 1];
cEdge.Length == 0
,你会得到System.IndexOutOfRangeException 应使用以下语法
testStr.Split( “” .ToCharArray(),StringSplitOptions.RemoveEmptyEntries);