【问题标题】:C# Why do I only get partial results when parsing out a CSV or TSV file?C# 为什么解析 CSV 或 TSV 文件时只得到部分结果?
【发布时间】:2011-08-03 13:35:30
【问题描述】:

我正在尝试从包含 100 行的 CSV 文件中获取第二个值。我得到了前 42 个值,然后它停止了……没有错误消息,或者根本没有错误处理。我很困惑,我在时间线上。它也对 TSV 文件执行此操作,但会给出前 43 个结果。如果你觉得奇怪,请帮忙告诉我。

我正在使用流式阅读器,将每一行读入一个字符串数组,拆分数组并获取第二个值并将其添加到列表中......

        string path = @"C:\Users\dave\Desktop\codes\testfile.txt";
        StreamReader sr = new StreamReader(path);
        List<string> stkno = new List<string>();

        foreach (var line in path)
        {
            string s = sr.ReadLine();
            string[] words = s.Split(',');
            stkno.Add(words[1]);
        }
        var message = string.Join(",", stkno.ToArray());
        MessageBox.Show(message);

【问题讨论】:

  • 没有例外?如果你单步执行循环会怎样?
  • @Dave_P - 请帮自己一个忙,不要使用该字符串来获取文件的路径。请简单地获取当前用户的桌面路径并从那里开始工作。您还可以考虑将文件本地放置到应用程序本身。
  • 你为什么要给我一个-1?

标签: c# visual-studio-2010 csv split generic-list


【解决方案1】:

您的 path 变量是一个字符串。这意味着当您 foreach 处理它时,您会得到一系列 字符 - 'C' 然后 ':' 然后 '\' 等等。我不认为这就是你的意思...

这是使用File.ReadLines 的更简单的方法:

string path = @"C:\Users\dave\Desktop\codes\testfile.txt";

List<string> stkno = (from line in File.ReadLines(path)
                      let words = line.Split(',')
                      select words[1]).ToList();

或者:

string path = @"C:\Users\dave\Desktop\codes\testfile.txt";

List<string> stkno = File.ReadLines(path)
                         .Select(line => line.Split(',')[1])
                         .ToList();

如果您使用的是 .NET 3.5,并且不介意一次读取整个文件,则可以改用 File.ReadAllLines

【讨论】:

  • 实际上,它正在从文件中读取行...它刚刚停止在 42%。不过,Matt Manela 帮我解决了问题,谢谢。
  • @Dave_P:您正在从文件中读取行,但只有当路径中有更多字符 - 这决定了您读取的行数。我相信我的迭代方法比明确使用 StreamReader 更干净。
【解决方案2】:

您意外地迭代了文件路径中的字符数,而不是字符串中的行数。此更改应该可以解决此问题:

    string path = @"C:\Users\dave\Desktop\codes\testfile.txt";
    StreamReader sr = new StreamReader(path);
    List<string> stkno = new List<string>();

    while (sr.Peek() >= 0) 
    {
        string s = sr.ReadLine();
        string[] words = s.Split(',');
        stkno.Add(words[1]);
    }
    var message = string.Join(",", stkno.ToArray());
    MessageBox.Show(message);

【讨论】:

  • 你摇滚。谢谢你的帮助。我曾一度尝试使用 peek,但也许我没有事先重建解决方案。问题解决了。能和天才在一起真是太好了。
  • 就我个人而言,我不喜欢这样使用 Peek - 调用 ReadLine 并查看它是否返回 null 会更干净,IMO。另请注意,这里没有 using 声明 - StreamReader 永远不会关闭。 (将 File.ReadLines 与 foreach 结合使用的另一个优点......不需要显式清理。)
  • @Jon Skeet,我完全同意你的观点,并建议按照你展示的方式实施它。我只是想让海报的代码保持相似。
【解决方案3】:

这个怎么样:

    string path = @"C:\Users\dave\Desktop\codes\testfile.txt";
    var secondWords = from line in File.ReadAllLines(path)
                        let words = line.Split(',')
                        select words[1];

    var message = string.Join(",", secondWords.ToArray());

【讨论】:

    【解决方案4】:

    我认为你的意思是:

        string path = @"C:\Users\dave\Desktop\codes\testfile.txt";
        StreamReader sr = new StreamReader(path);
        List<string> stkno = new List<string>();
    
        string s;
        while(s = sr.ReadLine() != null)
        {
            string[] words = s.Split(',');
            stkno.Add(words[1]);
        }
        var message = string.Join(",", stkno.ToArray());
        MessageBox.Show(message);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-17
      • 1970-01-01
      • 2018-05-29
      • 1970-01-01
      • 2022-10-20
      • 1970-01-01
      • 2021-10-08
      • 2018-02-22
      相关资源
      最近更新 更多