遇到.Split()方法有问题

时间:2012-04-15 05:27:44

标签: c# arrays split

此代码抛出异常,"索引超出了数组的范围"。这不应该只是将每个拆分数据添加到指定的数组插槽中吗?

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

6 个答案:

答案 0 :(得分:1)

检查你的字符串你可能没有输入5个元素并在split方法中提供一些字符

如果要用逗号分隔元素

,请将inputLine.Split()更改为inputLine.Split(',')

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

答案 1 :(得分: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,但这不是导致错误的原因。如果您读到文件末尾,则在尝试在拆分中使用空引用时会得到空引用异常。

答案 2 :(得分: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

答案 3 :(得分: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);
}

答案 4 :(得分:0)

在分割输入后在线上添加断点,然后可以将鼠标悬停在生成的数组上并单击加号。通过这种方式,您可以准确了解数据的分割方式。如果有隐藏的字符抛出分割(\ n,\ t,\ r),这将特别有用。

答案 5 :(得分: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
        }
    }
}