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] が最終列になります。それより大きいインデックスは、範囲外の例外を発生させます。

編集: コードを見て、最終的なインデックスを超えて実際にアクセスしようとしないことに気付いたので、最初の問題はおそらくクラッシュの原因ではありません。ここに別の提案があります。境界チェックを追加します。SplitLINQクエリで不完全な行を分割し、存在しないインデックスにアクセスしようとすると仮定します(つまり、行には4つのアイテムしかなく、無視する必要がありますが、コードは16とエラー行の範囲外のインデックスにアクセスしようとしています)。行を分割して 0 ~ n のインデックスにアクセスする場合は、その前に配列の長さが n より大きいことを確認してください。

于 2013-05-29T23:18:10.990 に答える
0

よくわかりませんが、頑張ってみます。配列に 16 個の項目がある場合、配列の最後の項目のインデックスは x[15] になります。これは、ほとんどの言語の配列が 1 ではなく 0 から数え始めるためです。配列の最初の項目のインデックスは x[ 0]。

私が追加する可能性のあるもう1つのことは、配列を取得して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 に答える
0

区切られたテキスト ファイルの読み取りは、一見したように単純ではありません。

セミコロンで区切られたファイルに 16 列がある場合、行を分割した結果の配列長さは 16 になります (つまり、配列への最大オフセットは +15 です)。ソース データのいずれかの行が次のいずれかに該当する場合は、これより少ない可能性があります。

  1. ファイルに短いレコードがあります。
  2. 1 つのフィールドに埋め込みの CR、LF、または CR+LF のペアが含まれているレコードがあるため、レコードが 2 つ (またはそれ以上) の行に分割され、上記のケース #1 になります。

思ったよりも多くの列ができてしまうかもしれません。この主な理由は、世界の不純物で汚染されているデータは、そのままでは多くの場合、汚れているためです。コンマやセミコロンなどの区切り文字でデータを散らかすことはよく知られています。テキストを単純Split()に処理すると、常に必要な結果が得られるとは限りません。そして、これは特に「CSV」ファイルに当てはまり、フォーマットはかなり [せき]大まかに定義されています。そしてさらに緩く実装されています。

これには、CodeProjectの Sebastien Lorion のFast CSV Readerの使用を検討してください。それは非常にうまく機能し、遭遇する可能性のある予期しないケースの多くを処理します.

あなたが見たいかもしれない他の参考文献:

注記:米国議会図書館は、CSV 形式についても検討しているようです: http://www.digitalpreservation.gov/formats/fdd/fdd000323.shtml

于 2013-05-29T23:26:17.277 に答える