【问题标题】:Adding CSV value to an array将 CSV 值添加到数组
【发布时间】:2020-06-28 10:51:56
【问题描述】:

我想将 CSV 值添加到数组中,但出现此错误:

索引超出了数组的范围。

这是我的代码:

try
{
    using (var reader = new StreamReader(@"/Users/ghost/Desktop/test.csv"))
    {
        List<string> listA = new List<string>();
        List<string> listB = new List<string>();

        while (!reader.EndOfStream)
        {
            var line = reader.ReadLine();
            var values = line.Split(';');
            listA.Add(values[0]);
            listB.Add(values[1]);
        }
    }
}
catch (Exception e)
{
    Console.WriteLine("The File could not be read:");
    Console.WriteLine(e.Message);

    Console.ReadLine();
}

【问题讨论】:

  • 其中一行读取没有 ;在里面。 (这不是这样做的方法)

标签: c# arrays .net visual-studio csv


【解决方案1】:

显而易见的答案是其中一行没有分号。因此Split 返回一个长度为1 的数组。访问此类数组的values[1] 会抛出异常。

您可以通过测试返回数组的大小并采取适当的措施来解决此问题。

var line = reader.ReadLine();
var values = line.Split(';'); 
listA.Add(values[0]); 
if (values.Length > 1)
   listB.Add(values[1]);

也许你想要一个空白的默认值:

if (values.Length > 1)
   listB.Add(values[1]);
else
   listB.Add(string.Empty);

或者您可以也完全跳过该行。如何操作取决于您,但您必须准备好处理此类情况,尤其是在您无法控制数据生成的情况下(例如,数据由用户或外部服务提供)。

如果您要处理大量 CSV 文件,我建议您不要自己尝试,而是选择像 CsvHelper 这样的第三方库。您还可以使用 .NET 的 TextFieldParser,虽然它不那么强大,但它比手动解决方案更好地处理 CSV 逻辑。

【讨论】:

    【解决方案2】:

    显然,一行不包含;,因此values[1] 在该行上无效。

    【讨论】:

    • 是的,你是对的。我必须输入','。谢谢兄弟
    【解决方案3】:

    您的 csv 文件中的分号之一之前或之后可能没有任何内容,这就是您收到错误的原因。错误:“索引超出了数组的范围”来自以下两行之一:

    listA.Add(values[0]);
    listB.Add(values[1]);
    

    【讨论】:

    • 之前或之后的文字在这里都没有关系,因为帖子不使用StringSplitOptions.RemoveEmptyEntries。连“;”行会有两个值(都是空的)答案是其中一行没有分号,因此返回一个大小为 1 的数组
    【解决方案4】:

    您不能立即创建数组,因为您需要从一开始就知道行数(这需要读取 csv 文件两次)

    您可以将值存储在两个List&lt;T&gt; 中,然后使用它们或使用List&lt;T&gt;.ToArray() 转换为数组

    var column1 = new List<string>();
    var column2 = new List<string>();
    using (var rd = new StreamReader("filename.csv"))
    {
        while (!rd.EndOfStream)
        {
            var splits = rd.ReadLine().Split(';');
            column1.Add(splits[0]);
            column2.Add(splits[1]);
        }
    }
    // print column1
    Console.WriteLine("Column 1:");
    foreach (var element in column1)
        Console.WriteLine(element);
    
    // print column2
    Console.WriteLine("Column 2:");
    foreach (var element in column2)
        Console.WriteLine(element);
    

    【讨论】:

      【解决方案5】:

      我建议您添加一个检查以消除异常。

      var values = line.Split(';');
      if(values.Length != 1)
      {
          listA.Add(values[0]);
          listB.Add(values[1]);
      }
      

      【讨论】:

      • 如果string.Split() 返回一个元素为零的数组,此代码将失败。您应该始终针对意外值进行防御性编程。
      • 你能提供一个例子,它会返回一个零元素的数组吗? @JonathanWood
      【解决方案6】:

      首先,StreamReader.ReadLine() 在您到达文件末尾时返回 null,因此请使用它来确定您何时完成读取所有行。

      其次,数组有一个Length 属性。用它来查看它包含多少元素。当数组只有一个或零个元素时,不要使用array[1]

      string line = reader.ReadLine();
      while (line != null)
      {
          var values = line.Split(';');
          if (values.Length >= 2)
          {
              listA.Add(values[0]);
              listB.Add(values[1]);
          }
          line = reader.ReadLine();
      }
      

      此外,某些 CSV 文件可以在字段中包含分号或换行符。所以string.Split() 并不总是足够的。要更复杂地处理分隔文件,您可能需要查看我的 SoftCircuits.CsvParser NuGet 包。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多