1

このコードは、「インデックスが配列の境界外にありました」という例外をスローしています。これは、分割された各データを指定された配列スロットに単純に追加するべきではありませんか?

while (input != null)
{
    string[] splitInput = inputLine.Split();
    EmpNum = int.Parse(splitInput[0]);
    EmpName = (splitInput[1]);
    EmpAdd = (splitInput[2]);
    EmpWage = double.Parse(splitInput[3]);
    EmpHours = double.Parse(splitInput[4]);
    inputLine = (myFile.ReadLine());
    Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours);
}

少し明確にするために、私は従業員データ(名前、住所、時間、従業員番号、賃金)を含む単純なテキストファイルからデータを読み取っています。

わかりやすくするために、メインのメソッド全体を追加しました。

using System;
using System.IO;

class Program
{
static void Main()
{

    //declare an array of employees
    Employee[] myEmployees = new Employee[10];

    //declare other variables
    string inputLine;
    string EmpName;
    int EmpNum;
    double EmpWage;
    double EmpHours;
    string EmpAdd;

    //declare filepath
    string environment =            System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal) + "\\";

    //get input
    Console.Write("\nEnter a file name in My Documents: ");
    string input = Console.ReadLine();
    string path = environment + input;
    Console.WriteLine("Opening the file...");

    //read file
    StreamReader myFile = new StreamReader(path);
    inputLine = (myFile.ReadLine());

    //split input
    while (inputLine != null)
    {

        string[] splitInput = inputLine.Split();
        EmpNum = int.Parse(splitInput[0]);
        EmpName = (splitInput[1]);
        EmpAdd = (splitInput[2]);
        EmpWage = double.Parse(splitInput[3]);
        EmpHours = double.Parse(splitInput[4]);
        Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours);
    }

    Console.ReadLine();
}//End Main()
}//End class Program
4

6 に答える 6

1

文字列を確認して、入力で5つの要素を取得していない可能性があり、splitメソッドで文字を指定してください

要素をコンマで区切る場合は、inputLine.Split()を に変更しますinputLine.Split(',')

入力は「1番目」、「2番目」、「3番目」、「4番目」、「5番目」のようになります

于 2012-04-15T05:30:56.990 に答える
1

十分なアイテムが含まれていない行があります。項目を読み取る前に、配列の長さを確認してください。

string[] splitInput = inputLine.Split();
if (splitInput.Length >= 5) {
  EmpNum = int.Parse(splitInput[0]);
  EmpName = (splitInput[1]);
  EmpAdd = (splitInput[2]);
  EmpWage = double.Parse(splitInput[3]);
  EmpHours = double.Parse(splitInput[4]);
} else {
  // not enough items - show an error message or something
}

また、inputではなく変数をチェックしていますが、それがエラーの原因ではありません。ファイルの最後まで読み取ると、分割でnull参照を使用しようとすると、null参照例外が発生します。inputLinewhere

于 2012-04-15T05:53:21.783 に答える
1

たぶん、このバージョンは追加のクレジットに適しています:)真剣に私はここで誇示しようとはしていませんが、それは学習例ですが、仕事を得て、CSVを読み取るコードを書くタスクを与えられた場合はそれだけですたとえば、ファイルがクラッシュして見栄えが悪くなることを望まないので、ファイルをより堅牢にするためのいくつかの手順について知っておくとよいでしょう。

注-これは、例をコーディングするための完璧な方法についての議論を開始する試みではありません-私が役立つとわかっているいくつかのトリックを示すことを試みるだけです。それがお役に立てば幸いです。

            StreamReader myFile = new StreamReader("TextFile1.txt");
            int lineNumber = 0;
            while (!myFile.EndOfStream)
            {
                // Read the next line.
                string inputLine = myFile.ReadLine();
                lineNumber++;

                // Extract fields line.
                string[] splitInput = inputLine.Split();

                // Make sure the line has the correct number of fields.
                if (splitInput.Length == 5)
                {
                    // Parse and validate each field.

                    if (!int.TryParse(splitInput[0], out EmpNum))
                    {
                        Console.WriteLine("could not parse int " + splitInput[0] + " on line " + lineNumber);
                        continue;
                    }

                    EmpName = (splitInput[1]);

                    EmpAdd = (splitInput[2]);

                    if(!double.TryParse(splitInput[3], out EmpWage))
                    {
                        Console.WriteLine("could not parse double " + " on line " + lineNumber);
                        continue;
                    }

                    EmpHours = double.Parse(splitInput[4]);

                    if (!double.TryParse(splitInput[4], out EmpHours))
                    {
                        Console.WriteLine("could not parse double: " + " on line " + lineNumber);
                        continue;
                    }

                    // Output
                    Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours);
                }
                else
                {
                    Console.WriteLine("Expecting 5 items from split opertation but got " + splitInput.Length  + " on line " + lineNumber);
                }
            }
            myFile.Close();

TextFile1.txt

1 2 3 4 5
6 7 8 f9 10
11 12

プログラム出力

test 1,5,5
could not parse double:  on line 2
Expecting 5 items from split opertation but got 2 on line 3
于 2012-04-15T06:17:01.890 に答える
0

1)あるべきではありませinputinputLineか?

2)使用する前に、すべての配列要素にnullチェックを追加します。

また、私は推測します、

while (input != null)
    {
        string[] splitInput = inputLine.Split();
        EmpNum = int.Parse(splitInput[0]);
        EmpName = (splitInput[1]);
        EmpAdd = (splitInput[2]);
        EmpWage = double.Parse(splitInput[3]);
        EmpHours = double.Parse(splitInput[4]);
        inputLine = (myFile.ReadLine());
        Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours);
    }

する必要があります

while (input != null)
    {
        inputLine = (myFile.ReadLine());
        string[] splitInput = inputLine.Split();
        EmpNum = int.Parse(splitInput[0]);
        EmpName = (splitInput[1]);
        EmpAdd = (splitInput[2]);
        EmpWage = double.Parse(splitInput[3]);
        EmpHours = double.Parse(splitInput[4]);

        Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours);

}

最初にを使用してファイルから読み取り、inputLine = (myFile.ReadLine()); 次に分割操作を実行します。

3)@Aaron Anodideが提案しているように、長さのチェックを追加するとうまくいくはずです。

何かのようなもの..

inputLine = (myFile.ReadLine());
string[] splitInput = inputLine.Split();
if(splitInput!=null && splitInput.length ==5)
{
 EmpNum = int.Parse(splitInput[0]);
        EmpName = (splitInput[1]);
        EmpAdd = (splitInput[2]);
        EmpWage = double.Parse(splitInput[3]);
        EmpHours = double.Parse(splitInput[4]);
        Console.WriteLine("test {0},{1},{2}", EmpNum, EmpWage, EmpHours);
}
于 2012-04-15T05:33:35.813 に答える
0

入力を分割した後、行にブレークポイントを追加します。次に、結果の配列にマウスを合わせて、プラス記号をクリックします。このようにして、データがどのように分割されているかを正確に確認できます。これは、分割を破棄する隠し文字がある場合に特に役立ちます(\ n、\ t、\ r)。

于 2012-04-15T05:53:21.617 に答える
0

いくつか問題があります。最初の問題は、Split()です。inputLine.Split()に変更する必要がありますinputLine.Split(',')。現在、のオーバーロードを呼び出していSystem.String.Split(params char[])ますが、分割する文字を指定していないため、文字列全体が返されます。

他の問題(CSの学生として)は、命名規則とエラーチェックに実際に取り組む必要があります。コードはかなりもろく、非常に簡単に壊れます。優れたソフトウェアエンジニアリングの実践を学び、高品質のコードを書くことから始めるべきです。

using (FileStream fstream = new FileStream("path", FileMode.Open))
using (StreamReader reader = new StreamReader(fstream)) {
    string line;

    while (!reader.EndOfStream && (line = reader.ReadLine()) != null) {
        string[] data = line.Split(',');

        if (data.Length < 5) {
            // You will have IndexOutOfRange issues
            continue; // skip processing the current loop
        }

        int employeeNumber;
        string employeeName;
        string employeeAddress;
        double employeeWage;
        double employeeHours;

        // Will be used to check validity of fields that require parsing into a type.
        bool valid;

        valid = int.TryParse(data[0], out employeeNumber);

        if (!valid) {
            // employee number is not parsable
        }

        employeeName = data[1];
        employeeAddress = data[2];

        valid = double.TryParse(data[3], out employeeWage);

        if (!valid) {
            // employee wage is not parsable
        }

        valid = double.TryParse(data[4], out employeeHours);

        if (!valid) {
            // employee hours are not parsable
        }
    }
}
于 2012-04-15T06:02:47.750 に答える