2012-04-15 74 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