2012-08-03 167 views
0

我正在嘗試使用c#讀取.txt文件並顯示其內容,但出現錯誤代碼爲IndexOutOfRangeException,錯誤代碼爲0xc000013a正在讀取.txt文件並顯示文件中的數字

這裏是我的代碼:

static void Main(string[] args) 
    { 
     StreamReader sStreamReader = new StreamReader("d:\\TEST.txt"); 
     while (!sStreamReader.EndOfStream) 
     { 
      string sLine = ""; 
      if (sLine != null) 
      { 
       sLine = sStreamReader.ReadLine(); 
       if (sLine != null) 
       { 
        string[] rows = sLine.Split(",".ToCharArray()); 
        double a = Convert.ToDouble(rows[1]); 
        Console.Write(a); 
        int b = Convert.ToInt32(rows[3]); 
        Console.WriteLine(b); 
        Console.WriteLine(); 
       } 
      } 
     } 
    } 

我的文本文件如下:

1,2,3,4,5,6,7 

1,2,3,4,5,6,7 

5,6,2,7,3,8,4 

3,4,3,4,3 

5,3,23,12 

12,30000,12,99 
+0

在這行你所得到的例外呢?這可能是因爲你正在讀取一些不是昏迷分隔的行,因此'split'方法並沒有返回你所期望的。 – npinti 2012-08-03 06:00:52

+0

順便說一句,不應該你的變量「行」實際上被稱爲「列」或「字段」? – 2012-08-03 06:03:39

+1

檢查你的文件是否有空行 也許在最後一行 – Karl 2012-08-03 06:09:27

回答

1

你有沒有考慮訪問row[1]row[3]

前檢查row.Length我懷疑你的空行是問題

0

你應該考慮使用:的

if (!string.IsNullOrEmpty(sLine)) 

代替

if (sLine != null) 

因爲一些線是空的,您有這樣的例外。

但是,這裏有一個方法使用一個StreamReader時,你應該寫代碼:

using(var reader = new StreamReader(@"d:\\TEST.txt")) 
{ 
    string line; 
    while ((line= reader.ReadLine()) != null) 
    { 
     if (string.IsNullOrEmpty(line)) continue; 

     var rows = line.Split(",".ToCharArray()); 
     var a = Convert.ToDouble(rows[1]); 
     Console.Write(a); 
     var b = Convert.ToInt32(rows[3]); 
     Console.WriteLine(b); 
     Console.WriteLine(); 
    } 
} 

問候,

凱文

2

我將它更改爲以下:

static void Main(string[] args) 
    { 
     // StreamReader is IDisposable which should be wrapped in a using statement 
     using (StreamReader reader = new StreamReader(@"d:\TEST.txt")) 
     { 
      while (!reader.EndOfStream) 
      { 
       string line = reader.ReadLine(); 
       // make sure we have something to work with 
       if (String.IsNullOrEmpty(line)) continue; 

       string[] cols = line.Split(','); 
       // make sure we have the minimum number of columns to process 
       if (cols.Length < 4) continue; 

       double a = Convert.ToDouble(cols[1]); 
       Console.Write(a); 
       int b = Convert.ToInt32(cols[3]); 
       Console.WriteLine(b); 
       Console.WriteLine(); 
      } 
     } 
    } 

這裏有一些注意事項:

  1. StreamReader實現了IDisposable,所以你應該把它包裝在一個using子句中,以便正確處理它。
  2. 不要命名爲「sLine」。這種匈牙利形式通常被認爲是嚴重不良的做法。即使微軟說不要這樣做。
  3. 你正在處理的是列,而不是行。所以這個變量應該適當地命名。
  4. 在盲目地訪問它們之前,請務必測試以確保您擁有所有需要的列。
  5. 通常,我不會使用Convert.ToDouble或Convert.ToInt32。使用TryParse確保它能夠轉換更安全。如果cols [1]和cols [3]具有非數字數據,那麼您的代碼將會受到攻擊。
  6. 您可以在字符串前面使用@符號來告訴編譯器它不需要轉義。
  7. 簡單地「繼續」一個循環而不是將其包裝在if語句中會更簡潔。
  8. 將字符串變量設置爲空字符串,然後立即將其設置爲某個其他值,導致空白留在整個範圍的內存中。換句話說,這是在浪費記憶。誠然,在這種情況下,這是一種微型優化,但它永遠不會傷害到使用最佳實踐。
1

這裏是你如何能做到這簡單:

 string[] lines = File.ReadAllLines("d:\\TEST.txt"); 
     foreach (var line in lines.Where(line => line.Length > 0)) 
     { 
      string[] numbers = line.Split(','); 

      // It checks whether numbers.Length is greater than 
      // 3 because if maximum index used is 3 (numbers[3]) 
      // than the array has to contain at least 4 elements 
      if (numbers.Length > 3) 
      { 
       double a = Convert.ToDouble(numbers[1]); 
       Console.Write(a); 
       int b = Convert.ToInt32(numbers[3]); 
       Console.Write(b); 
       Console.WriteLine(); 
      } 
     } 
+1

+1:我把linq的使用聯繫起來以找出那些有* something *的行。我建議你在訪問數組之前添加一個檢查驗證數組中是否有正確數量的元素。此外,您可能會對最初的ReadAllLines進行說明,這對於有限的數據量非常有用;但對OP來說可能是完美的。 – NotMe 2012-08-03 13:56:34

+0

@ChrisLively謝謝克里斯,會那樣做。 – 2012-08-03 17:20:22