0

我正在开发一个使用 C# 重新格式化 CSV 文件的程序。它导入 CSV 并使用某些列在新的 CSV 文件中表示。使用此代码,我得到一个 System.IndexOutOfRangeException 异常。

using System;
using System.Collections;
using System.Linq;

class CSVFiles
{
    static void Main(string[] args)
    {
        // Create the IEnumerable data source 
        string[] lines = System.IO.File.ReadAllLines(@"presta.csv");

        // Create the query. Put field 2 first, then 
        // reverse and combine fields 0 and 1 from the old field
        IEnumerable query =
            from line in lines
            let x = line.Split(';')
            select x[0] + ", base, 0, " + x[0] + ", " + x[7] + ", " + x[1] + ", " + x[2] + ", " + x[3] + ", " + x[15] + ", " + x[4] + ", " + x[6] + ", " + x[7] + ", Sí, " + x[12] + ", " + x[12] + ", " + x[12] + ", " + x[12];

        // Execute the query and write out the new file. Note that WriteAllLines 
        // takes a string[], so ToArray is called on the query.
        System.IO.File.WriteAllLines(@"outlet.csv", query.Cast<String>().ToArray());

        Console.WriteLine("outlet.csv written to disk. Press any key to exit");
        Console.ReadKey();
    }
}

导入的 CSV 有 16 列,所以它应该被索引到 x[17]。谁可以帮我这个事?或者也许还有另一种更好的方法?

这是整个调试输出:

'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities\11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities.Sync\11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.Sync.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.Debugger.Runtime\11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Debugger.Runtime.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'c:\users\daniel\documents\visual studio 2012\Projects\CSVConverter\CSVConverter\bin\Debug\CSVConverter.vshost.exe'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml.Linq\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.Linq.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Data.DataSetExtensions\v4.0_4.0.0.0__b77a5c561934e089\System.Data.DataSetExtensions.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.CSharp\v4.0_4.0.0.0__b03f5f7f11d50a3a\Microsoft.CSharp.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_32\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll'
The thread 'vshost.NotifyLoad' (0x52c) has exited with code 0 (0x0).
The thread 'vshost.LoadReference' (0x6cc) has exited with code 0 (0x0).
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'c:\users\daniel\documents\visual studio 2012\Projects\CSVConverter\CSVConverter\bin\Debug\CSVConverter.exe', Symbols loaded.
A first chance exception of type 'System.IndexOutOfRangeException' occurred in CSVConverter.exe
An unhandled exception of type 'System.IndexOutOfRangeException' occurred in CSVConverter.exe
Additional information: Index was outside the bounds of the array.
The program '[6952] CSVConverter.vshost.exe: Managed (v4.0.30319)' has exited with code -1073741510 (0xc000013a).
4

4 回答 4

1

你说“导入的 CSV 有 16 列,所以它应该被索引到 x[17]。” 那是错的。数组索引为 0,因此如果 CSV 有 16 列 x[15] 将是最后一列。任何大于该值的索引都会给出越界异常。

编辑:查看您的代码,我注意到您实际上并没有尝试访问超出最终索引的任何内容,因此第一个问题可能与您的崩溃无关;这是另一个建议。添加一些边界检查。我会假设Split在您的 LINQ 查询中拆分了一个不完整的行,然后您尝试访问不存在的索引(即该行上只有 4 个项目,应该被忽略,但您的代码只是假设它有 16 个和尝试访问错误行中超出范围的索引)。如果您拆分一行并要访问 0 和 n 之间的索引,请在执行此操作之前检查以确保数组长度大于 n。

于 2013-05-29T23:18:10.990 回答
0

读取带分隔符的文本文件并不像最初看起来那么简单。

如果您的以分号分隔的文件有 16 列,则拆分行产生的数组的长度为 16(意味着数组中的最高偏移量为 +15)。如果源数据中的任何行满足以下任何一项,则可能会更少:

  1. 您在文件中有一条简短的记录。
  2. 您有一条记录,其中一个字段包含嵌入的 CR、LF 或 CR+LF 对,因此将记录分成两行(或多行)并导致上述情况 #1。

你可能会得到比你想象的更多的列。造成这种情况的主要原因是,被世界杂质污染的数据通常是不干净的。人们已经知道使用分隔符(例如逗号或分号)乱扔数据。当你Split()在文本上做一个幼稚的时候,你并不总是得到你想要的。这对于“CSV”文件尤其如此,格式相当[咳嗽]松散定义。甚至更松散地实施。

为此,您可能想看看使用 CodeProject 中的 Sebastien Lorion 的Fast CSV Reader。它工作得很好,可以处理很多你可能遇到的……意外情况。

您可能想查看的其他参考资料:

编辑注意:国会图书馆似乎也对 CSV 格式进行了权衡:http ://www.digitalpreservation.gov/formats/fdd/fdd000323.shtml

于 2013-05-29T23:26:17.277 回答
0

我不确定我是否理解,但我会尽力而为。如果数组中有 16 项,则数组中最后一项的索引将是 x[15],因为大多数语言中的数组从 0 而不是 1 开始计数。数组中第一项的索引是 x[ 0]。

我可能要补充的另一件事是,看起来您正在获取一个数组,将其转换为 IEnumerable,然后将其转换回数组,而无需使用 IEnumerable 提供的任何花哨的东西。我建议改为使用 foreach 循环来完成此任务。

祝你好运,希望这有帮助!

于 2013-05-29T23:33:22.390 回答
0

您可能有一个额外的换行符(尤其是在文件末尾),它给出了一个空白字符串。要解决此问题,您可以将您的where条件修改为:

from line in lines
where !String.IsNullOrEmpty(line)
...
于 2013-05-29T23:23:52.410 回答