2009-09-03 94 views
34

我想從CSV文件創建一個數組。非常簡單的C#CSV閱讀器

這是,你可以想像一樣簡單,CSV文件將只擁有一條線,並且這些值:

Device, SignalStrength, Location, Time, Age. 

我希望把這些值轉換成一個維數組。

我試過一些例子,但它們都比要求更復雜。

+3

味道有點homeworky使用我的圖書館

簡單的例子 – annakata 2009-09-03 19:26:23

+0

「進入一維數組」聽起來很奇怪,你確定要丟掉換行符信息嗎? – 2009-09-03 19:47:57

+0

@HenkHolterman OP的狀態只會有一行 – KingCronus 2012-04-25 09:22:16

回答

50

如果有那麼永遠只能一條線做這樣的事情:

using System; 
using System.IO; 

class Program 
{ 
    static void Main() 
    { 
     String[] values = File.ReadAllText(@"d:\test.csv").Split(','); 
    } 
} 
+73

不,不,不,這太複雜了! – ChaosPandion 2010-01-28 06:21:21

+103

如果任何字段包含逗號,則會失敗。 – 2012-06-22 00:12:54

+5

你如何處理新的線? – nonsensickle 2014-01-13 02:52:38

62

你可以嘗試像下面的LINQ片段中的一些事情。

string[] allLines = File.ReadAllLines(@"E:\Temp\data.csv"); 

    var query = from line in allLines 
       let data = line.Split(',') 
       select new 
       { 
        Device = data[0], 
        SignalStrength = data[1], 
        Location = data[2], 
        Time = data[3], 
        Age = Convert.ToInt16(data[4]) 
       }; 

UPDATE:過了一段時間,事情演變。截至目前,我寧願使用這個庫http://www.aspnetperformance.com/post/LINQ-to-CSV-library.aspx

+6

嗨Ramesh ..你的解決方案是偉大的..但你怎麼逃避逗號?? – andrew0007 2011-04-11 14:58:15

+0

@ andrew007 - 我腦海中第一件事是使用正則表達式分裂。檢查出http://regexadvice.com/blogs/ wayneking/archive/2004/01/12/271.aspx – Ramesh 2011-04-14 15:22:20

+14

@ramesh「有些人在遇到問題時想'我知道,我會用正則表達式'。現在他們有兩個問題。「 - Jamie Zawinski。看看http://secretgeek.net/csv_trouble.asp。 – 2011-12-09 04:00:56

7

這是我做的一個簡單的函數。它接受一個字符串CSV行並返回一組字段:

它與Excel生成的CSV文件以及許多其他變體一起工作良好。

public static string[] ParseCsvRow(string r) 
    { 

     string[] c; 
     string t; 
     List<string> resp = new List<string>(); 
     bool cont = false; 
     string cs = ""; 

     c = r.Split(new char[] { ',' }, StringSplitOptions.None); 

     foreach (string y in c) 
     { 
      string x = y; 


      if (cont) 
      { 
       // End of field 
       if (x.EndsWith("\"")) 
       { 
        cs += "," + x.Substring(0, x.Length - 1); 
        resp.Add(cs); 
        cs = ""; 
        cont = false; 
        continue; 

       } 
       else 
       { 
        // Field still not ended 
        cs += "," + x; 
        continue; 
       } 
      } 

      // Fully encapsulated with no comma within 
      if (x.StartsWith("\"") && x.EndsWith("\"")) 
      { 
       if ((x.EndsWith("\"\"") && !x.EndsWith("\"\"\"")) && x != "\"\"") 
       { 
        cont = true; 
        cs = x; 
        continue; 
       } 

       resp.Add(x.Substring(1, x.Length - 2)); 
       continue; 
      } 

      // Start of encapsulation but comma has split it into at least next field 
      if (x.StartsWith("\"") && !x.EndsWith("\"")) 
      { 
       cont = true; 
       cs += x.Substring(1); 
       continue; 
      } 

      // Non encapsulated complete field 
      resp.Add(x); 

     } 

     return resp.ToArray(); 

    } 
+1

當你失敗時「cell2」,「,,,,,,,,」previous failed「 – MurWade 2015-03-13 03:37:09

3

這是我在項目中使用的,分析一行數據。

private string[] csvParser(string csv, char separator = ',') 
    { 
     List <string> = new <string>(); 
     string[] temp = csv.Split(separator); 
     int counter = 0; 
     string data = string.Empty; 
     while (counter < temp.Length) 
     { 
      data = temp[counter].Trim(); 
      if (data.Trim().StartsWith("\"")) 
      { 
       bool isLast = false; 
       while (!isLast && counter < temp.Length) 
       { 
        data += separator.ToString() + temp[counter + 1]; 
        counter++; 
        isLast = (temp[counter].Trim().EndsWith("\"")); 
       } 
      } 
      parsed.Add(data); 
      counter++; 
     } 

     return parsed.ToArray(); 

    } 

http://zamirsblog.blogspot.com/2013/09/c-csv-parser-csvparser.html

+0

我認爲第3行應該是: List parsed = new列表(); – Matiaan 2015-04-20 11:16:36

+0

不錯,但不幸的是, out of array boundary「異常行數據+ = separator.ToString()+ temp [counter + 1];在一個格式良好的行上:( – AFract 2015-10-13 08:45:42

2

我的解決辦法處理報價,覆蓋領域和字符串分隔符等,這是簡短而親切。

public static string[] CSVRowToStringArray(string r, char fieldSep = ',', char stringSep = '\"') 
    { 
     bool bolQuote = false; 
     StringBuilder bld = new StringBuilder(); 
     List<string> retAry = new List<string>(); 

     foreach (char c in r.ToCharArray()) 
      if ((c == fieldSep && !bolQuote)) 
      { 
       retAry.Add(bld.ToString()); 
       bld.Clear(); 
      } 
      else 
       if (c == stringSep) 
        bolQuote = !bolQuote; 
       else 
        bld.Append(c); 

     return retAry.ToArray(); 
    } 
+0

該解決方案似乎失去了行上的最後一個值,即使是非常簡單的測試沒有報價 – AFract 2015-10-13 08:44:01

3

上述該固定的代碼版本記得CVS行;-)的最後一個元素

(具有CSV測試了5400行和由行26個元素文件)

public static string[] CSVRowToStringArray(string r, char fieldSep = ',', char stringSep = '\"') { 
      bool bolQuote = false; 
      StringBuilder bld = new StringBuilder(); 
      List<string> retAry = new List<string>(); 

      foreach (char c in r.ToCharArray()) 
       if ((c == fieldSep && !bolQuote)) 
       { 
        retAry.Add(bld.ToString()); 
        bld.Clear(); 
       } 
       else 
        if (c == stringSep) 
         bolQuote = !bolQuote; 
        else 
         bld.Append(c); 

      /* to solve the last element problem */ 
      retAry.Add(bld.ToString()); /* added this line */ 
      return retAry.ToArray(); 
     } 
-1

首先需要了解什麼是CSV以及如何編寫它。

  1. 下一個字符串(/r/n)是下一個「表」行。
  2. 「表」單元格由某個分隔符號分隔。最常用的符號是\t,
  3. 每一個細胞可能可以包含該定界符(單元必須先從報價符號,並在這種情況下,這個符號結束)
  4. 每個細胞都可能會包含/r/n sybols(細胞一定要在這種情況下,以引號符號開頭,並以此符號結尾)

前一段時間,我基於標準Microsoft.VisualBasic.FileIO庫編寫了簡單的CSV讀/寫類。使用這個簡單的類,你將能夠像使用2維數組一樣使用CSV。

Csv csv = new Csv("\t");//delimiter symbol 

csv.FileOpen("c:\\file1.csv"); 

var row1Cell6Value = csv.Rows[0][5]; 

csv.AddRow("asdf","asdffffff","5") 

csv.FileSave("c:\\file2.csv"); 

您可以通過下面的鏈接找到我的課,探討它是怎麼寫的: - 告訴我們你有什麼到目前爲止 https://github.com/ukushu/DataExporter