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

也许这个版本会获得额外的荣誉 :) 说真的,虽然我不想在这里炫耀 - 只是即使它是一个学习示例,如果你找到一份工作并被赋予编写读取 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();

文本文件1.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 回答
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而不是inputLine在 中where,但这不是您得到错误的原因。如果您阅读到文件末尾,则在尝试使用拆分中的空引用时会收到空引用异常。

于 2012-04-15T05:53:21.783 回答
1

检查您的字符串,您可能没有在输入中获得 5 个元素并在拆分方法中提供一些字符

更改inputLine.Split()inputLine.Split(','),如果您用逗号分隔元素

您的输入将像“第一”、“第二”、“第三”、“第四”、“第五”

于 2012-04-15T05:30:56.990 回答
0

在拆分输入后在行中添加一个断点,然后您可以将鼠标悬停在结果数组上并单击加号。这样您就可以准确地看到数据是如何被拆分的。如果存在会导致拆分的隐藏字符 (\n,\t,\r),这将特别有用。

于 2012-04-15T05:53:21.617 回答
0

1)不input应该inputLine吗?

2)在使用它之前为每个数组元素添加一个空检查。

我也猜,

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

你有几个问题。第一个问题是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 回答