2014-04-03 59 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