2012-04-15 71 views
1

此代码抛出异常,“索引超出了数组边界”。不应该这样简单地将每个分割数据添加到指定的数组插槽中吗?使用.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 
+0

另外,如果需要任何其他信息,我可以发布更多的我的代码。 – xavi 2012-04-15 05:28:47

+0

当你分割你的'inputLine'时,你得到少于5个元素 – bjarneh 2012-04-15 05:30:07

+0

不应该'while(input!= null)'而不是'while(inputLine!= null)'? – 2012-04-15 05:30:43

回答

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 
+0

谢谢!这是美丽的 – xavi 2012-04-15 06:25:18

+0

很高兴帮助... – 2012-04-15 06:31:46

1

检查你的字符串,你可能不会得到输入5种元素和分割方法提供了一些字符

更改inputLine.Split()inputLine.Split(','),如果你是用逗号

分离元件

您输入的内容如“第一”,“第二”,“第三”,“第四”,“第五”

+0

我开始意识到我的错误。好。所以我创建了一个名为“Employee”的类,并创建了一个由10个这样的员工对象组成的数组。我真正需要做的是从这个文件中读取数据,并将引用存储在这个员工对象数组中。希望这可以解决问题。 – xavi 2012-04-15 05:59:54

+0

在文件中重复这种模式,并使5行“第一”,“第二”,“第三”,“第四”,“第五”,然后读取文件的输入,你可以找到如何从这里的文件读取http://msdn.microsoft .com/en-us/library/ms228592(v = vs.80).aspx – Adil 2012-04-15 06:06:51

0

1)应该不是inputinputLine

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的建议,插件GA检查长度应该做的伎俩..

像..

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); 
} 
+1

如何在分割操作之后向数组中添加数组长度检查?我认为这会对海报有所帮助...... – 2012-04-15 05:36:57

+0

检查数组中的空值完全没有帮助。数组中不会有任何空值。 – Guffa 2012-04-15 05:51:22

+0

@Guffa:你的意思是数组或数组元素?如果您引用'splitInput!= null',那么在使用属性之前,我已经将它添加到了更安全的一面。如果你指的是数组元素,那么说一个文件中的一行只包含3个元素,其他元素是不是null? – 2012-04-15 05:56:06

0

添加一个破发点行拆分输入后,那么你可以鼠标所产生的阵列上,然后点击加号。通过这种方式,您可以准确了解数据如何分割。如果有隐藏的字符会导致分割(\ n,\ t,\ r),这特别有用。

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,而不是inputLinewhere,但是这不是你的错误的原因。如果你读到文件末尾,当试图在分割中使用空引用时,你会得到一个空引用异常。

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 
     } 
    } 
} 
+0

感谢您的建议! – xavi 2012-04-15 06:15:13

+0

也可以,你可以解释有效的布尔?我感谢你的回答! – xavi 2012-04-15 06:24:59

+0

这是检查格式不正确的数据。如果数据格式不正确,double.Parse会抛出异常。假设您的数据文件意外地包含一个'-'字符(输入0后通用)。 'double.Parse'会失败并抛出异常。解决方案是使用'double.TryParse',如果输入成功转换为double,则返回true,否则返回false(数据格式错误)。这可以防止抛出异常,并允许您在代码中正常处理问题。 – 2012-04-15 06:41:38