系统.CSV重格式化程序中的IndexOutOfRangeException

本文关键字:IndexOutOfRangeException 程序 格式化 CSV 系统 | 更新日期: 2023-09-27 18:15:53

我正在编写一个使用c#重新格式化CSV文件的程序。它导入CSV并使用某些列在新的CSV文件中表示。我有一个系统。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).

系统.CSV重格式化程序中的IndexOutOfRangeException

您说"导入的CSV有16列,因此应该索引到x[17]",这是错误的。数组是0索引的,所以如果CSV有16列,x[15]将是最后一列。任何大于这个值的索引都会抛出越界异常。

编辑:看着你的代码,我注意到,你实际上并没有尝试访问任何超出最终索引所以第一个问题可能不是负责你的崩溃;这是另一个建议。添加一些边界检查。我会假设Split在你的LINQ查询分裂一个不完整的行,然后你尝试访问索引不存在(即行只有4个项目,应该被忽略,但你的代码只是假设它有16,并试图访问一个索引是超出范围的错误行)。如果分割一行,并且要访问0到n之间的索引,那么在这样做之前,请检查数组长度是否大于n。

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

如果以分号分隔的文件有16列,分隔行产生的数组的长度应为 16(这意味着对数组的最大偏移量为+15)。如果小于,则对于源数据中的任何一行

为真:
  1. 您在文件中有一个短记录。
  2. 您有一个记录,其中一个字段包含嵌入式CR, LF或CR+LF对,从而将记录分成两(或更多)行,并导致上述情况#1。

您可能也会得到比您想象的更多的列。造成这种情况的主要原因是,数据被世界的不洁净所污染,因为它通常是不洁净的。人们已经知道用分隔符(如逗号或分号)乱扔数据。当你在文本上做一个天真的Split()时,你并不总是得到你想要的。对于"CSV"文件来说尤其如此,因为该格式的定义非常松散。甚至更松散的实现。

你可能想看看使用Sebastien Lorion的快速CSV阅读器从CodeProject。它工作得很好,照顾了很多……可能遇到的意外情况

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

  • RFC 4180, 逗号分隔值(CSV)文件的通用格式和MIME类型
  • http://creativyst.com/Doc/Articles/CSV/CSV01.htm
  • http://en.wikipedia.org/wiki/Comma-separated_values

编辑说明:国会图书馆似乎也在权衡CSV格式:http://www.digitalpreservation.gov/formats/fdd/fdd000323.shtml

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

from line in lines
where !String.IsNullOrEmpty(line)
...

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

我要补充的另一件事是,它看起来像你正在获得一个数组,将其转换为IEnumerable,然后将其转换回数组,而不使用IEnumerable提供的任何花哨的东西。我建议使用foreach循环来完成这个任务。

祝你好运,希望这篇文章对你有所帮助!