2014-04-03 103 views
0

我有一個小程序讀入一個CSV文件,其中包含一個由逗號分隔的報告。在報告中,其中一個字段是一個日期,我將其轉換爲日期/時間,並且只從特定時間範圍內提取信息。儘管這是我的問題:報告實際上是在特定系統上運行的作業列表。然而,一些工作名稱包含逗號。這意味着Excel輸出報告非常混亂,因爲如果作業名稱有逗號,則作業名稱將被分爲2個單元格。我對編程有點新,所以我唯一能想到的解決方法是檢查我的數組中有多少字段以逗號分隔。如果它比正常情況更大,我會連接兩個我知道將作爲工作名稱的字段。但是,問題是如果一個工作名稱包含2個逗號,這將不起作用,因爲它只設置爲處理數據中的一個額外逗號。從另一個陣列中替換陣列字段

我應該添加,我讀入的CSV報告是由另一個應用程序生成的,我無法控制它的分隔方式。否則,我會改變它到管道或類似的東西。

有什麼想法?下面是處理它的代碼部分:

StreamReader SR = new StreamReader(inputFile); 
StreamWriter SW = new StreamWriter(outputFile); 
string records; 
//read headers from first line 
string headers = records = SR.ReadLine(); 
SW.WriteLine(headers); 
DateTime YesterdayAM = Convert.ToDateTime(DateTime.Now.AddDays(-1).ToShortDateString() + " 05:00:00 AM"); 
while ((records = SR.ReadLine()) != null) 
{ 
    if (records.Trim().Length > 0) 
    { 
     string daterecord = GetDateTimeFromStringArray(records); 
     if (daterecord.Length > 0) 
     { 
      DateTime recordDate = Convert.ToDateTime(daterecord); 
      if (recordDate >= YesterdayAM) 
      { 
       string[] checkfields = records.Split(','); 
       if (checkfields.Length > 13) 
       { 
        string[] replacefields = { checkfields[0], checkfields[1] + " " + checkfields[2], checkfields[3], checkfields[4], checkfields[5], checkfields[6], checkfields[7], checkfields[8], checkfields[9], checkfields[10], checkfields[11], checkfields[12] }; 
        for (int i = 0; i < replacefields.Length; i++) 
        { 
         SW.Write(replacefields[i] + ","); 
        } 
        SW.Write(Environment.NewLine); 
       } 
       else 
       { 
        SW.WriteLine(records); 
       } 
      } 
     } 
    } 
} 
+0

我認爲這是一個類似的問題:http://stackoverflow.com/questions/769621/dealing-with-commas-in-a-csv-file – skeryl

+0

通常,在CSV文件中,如果您的單元格包含分隔符,應該用引號括起來。這就是Excel在保存爲CSV時可以處理任何包含逗號的單元格。如果這是完全不可能的,那麼使用你描述的技術,你可以通過調用方法再次連接字段直到長度正確,在作業名稱字段中處理多個逗號。 –

回答

0

這是一個有點哈克做這種方式,但如果你不能修復的來源和你知道額外的逗號只會出現在一個領域,你可以做這樣的事情:

  string[] checkfields = records.Split(','); 
      while (checkfields.Length > 13) 
      { 
       // concat [1] & [2] into a new array 
       checkfields = checkfields.Take(1) 
        .Concat(new string[] { string.Join("", checkfields.Skip(1).Take(2).ToArray()) }) 
        .Concat(checkfields.Skip(3)).ToArray(); 
      } // if it's still too long it will loop again 

或者更好的是:

  string[] checkfields = records.Split(','); 
      int extraFields = checkfields.Length - 13; 
      if (extraFields > 0) 
      { 
       // concat fields 1....1 + extraFields 
       checkfields = checkfields.Take(1) 
        .Concat(new string[] { string.Join("", checkfields.Skip(1).Take(extraFields).ToArray()) }) 
        .Concat(checkfields.Skip(extraFields + 1)).ToArray(); 
      } // avoids looping by doing it all in one go 

注:LINQ聲明未經測試,可能不是絕對的最有效的方法來做到這一點。而且所有的「魔術」數字都應該用可維護性的常量代替。

+0

非常感謝大家!我很感激。我將嘗試你的第二種方法。 – user3494110