尝试读取csv文件时出错

时间:2015-06-18 06:48:32

标签: c# csv

美好的一天,

我在asp.net项目中读取csv文件时遇到问题。

它总是返回超出范围的错误索引,找不到第6列

在我继续解释我在这里做的是代码之前:

for (index, element) in enumerate(userCoordinates) {
    println("\(element)")
}

我尝试使用逗号分隔列,但随附的字符串包含逗号,所以我尝试了 - 符号只是为了确保文本文件中没有多余的逗号,但是弹出相同的错误。

我做错了什么?

提前谢谢

3 个答案:

答案 0 :(得分:0)

对于一行或多行,您的Excel文件可能包含的列数多于6。出于这个原因,内部foreach中的拆分会找到更多列,但是tblcsv没有比6更多的列来分配额外的列值。

尝试这样的事情:

foreach (string FileRec in csvRow.Split('-'))
{
    if(count > 5)
        return;
    tblcsv.Rows[tblcsv.Rows.Count - 1][count] = FileRec;
    count++;
}

但是,如果在处理之前检查其他列并处理问题会更好。

答案 1 :(得分:0)

StringBuilder errors = new StringBuilder();   //// this will hold the record for those array which have length greater than the 6

foreach (string csvRow in ReadCSV.Split('\n'))
                {
                    if (!string.IsNullOrEmpty(csvRow))
                    {
                        //Adding each row into datatable  
                       DataRow dr = tblcsv.NewRow(); and then  
                        int count = 0;
                        foreach (string FileRec in csvRow.Split('-'))
                        {
                     try
                      {
                           dr[count] = FileRec;
                            tblcsv.Rows.Add(dr);
                      }
                     catch (IndexOutOfRangeException i)
                     {
                     error.AppendLine(csvRow;)
                     break;
                     }
                            count++;
                    }
                    }
                }

现在在这种情况下,我们将了解导致错误的csv行,并且将成功处理其余部分。验证错误中的行是否是所需的输入,如果不是则在csv文件中验证正确的值。

答案 2 :(得分:0)

如果分隔符出现在字段内,则无法将文件视为CSV。在这种情况下,您可以使用正则表达式将前五个字段提取到破折号,然后将该行的其余部分作为第六个字段读取。使用正则表达式,您可以匹配整个字符串,甚至避免分割线。

正则表达式也比分割快很多,并且消耗更少的内存,因为它们不会创建临时字符串。这就是为什么它们被广泛用于解析日志文件的原因。按名称捕获字段的能力不会受到影响

以下示例解析整个文件并捕获命名组中的每个字段。最后一个字段捕获到行尾的所有内容:

var pattern="^(?<latitude>.*?)-(?<longitude>.*?)-(?<mps>.*?)-(?<activity_type>.*?)-" +
            "(?<date_occured>.*?)-(?<detail>.*)$";
var regex=new Regex(pattern,RegexOptions.Multiline);
var matches=regex.Matches(forex);

foreach (Match match in matches)
{
    DataRow dr = tblcsv.NewRow();
    row["latitude"]=match.Groups["latitude"].Value);
    row["longitude"]=match.Groups["longitude"].Value);
    ...
    tblcsv.Rows.Add(dr);
}

(?<latitude>.*?)-模式将第一个短划线的所有内容捕获到名为latitude的组中。 .*?模式意味着匹配并不贪婪,即它不会尝试将所有内容捕获到行尾,但会在遇到第一个-时停止。

列名称与字段名称匹配,这意味着您可以使用循环添加所有字段:

foreach (Match match in matches)
{
    var row = tblCsv.NewRow();
    foreach (Group group in match.Groups)
    {
        foreach (DataColumn col in tblCsv.Columns)
        {
            row[col.ColumnName]=match.Groups[col.ColumnName].Value;                        
        }                    
    }
    tblCsv.Rows.Add(row);
}
tblCsv.Rows.Add(row);