【问题标题】:Parsing .csv files with CR LF EOL structure解析具有 CR LF EOL 结构的 .csv 文件
【发布时间】:2015-05-01 15:39:24
【问题描述】:

我正在尝试解析 CSV 文件,而 getline() 正在将整个文件作为一行读取。假设getline() 没有达到预期的效果,我尝试将\r\n\n\r\r\n\0 作为参数,但没有成功。

我查看了 EOL 字符并查看了 CRLFgetline() 只是忽略了这一点还是我错过了什么?另外,这里的解决方法是什么?

此函数的目标是一个通用的 CSV 解析函数,它将数据存储为字符串的二维向量。尽管欢迎在这方面提出建议,但我只是在寻找解决此问题的方法。

vector<vector<string>> Parse::parseCSV(string file)
{
    // input fstream instance
    ifstream inFile;
    inFile.open(file);

    // check for error
    if (inFile.fail()) { cerr << "Cannot open file" << endl; exit(1); }

    vector<vector<string>> data;
    string line;

    while (getline(inFile, line))
    {
        stringstream inputLine(line);
        char delimeter = ',';
        string word;
        vector<string> brokenLine;
        while (getline(inputLine, word, delimeter)) {
            word.erase(remove(word.begin(), word.end(), ' '), word.end());      // remove all white spaces
            brokenLine.push_back(word);
        }
        data.push_back(brokenLine);
    }

    inFile.close();

    return data;

};

这里是十六进制转储。我不确定这到底显示了什么。

0000000 55 4e 49 58 20 54 49 4d 45 2c 54 49 4d 45 2c 4c
0000010 41 54 2c 4c 4f 4e 47 2c 41 4c 54 2c 44 49 53 54
0000020 2c 48 52 2c 43 41 44 2c 54 45 4d 50 2c 50 4f 57
0000030 45 52 0d 31 34 32 34 31 30 35 38 30 38 2c 32 30
0000040 31 35 2d 30 32 2d 31 36 54 31 36 3a 35 36 3a 34
0000050 38 5a 2c 34 33 2e 38 39 36 34 2c 31 30 2e 32 32
0000060 34 34 34 2c 30 2e 38 37 2c 30 2c 30 2c 30 2c 4e
0000070 6f 20 44 61 74 61 2c 4e 6f 20 44 61 74 61 0d 31
0000080 34 32 34 31 30 35 38 38 35 2c 32 30 31 35 2d 30
0000090 32 2d 31 36 54 31 36 3a 35 38 3a 30 35 5a 2c 34
00000a0 33 2e 39 30 31 33 35 2c 31 30 2e 32 32 30 34 31
00000b0 2c 31 2e 30 32 2c 30 2e 36 33 39 2c 30 2c 30 2c
00000c0 4e 6f 20 44 61 74 61 2c 4e 6f 20 44 61 74 61 0d
00000d0 31 34 32 34 31 30 35 38 38 38 2c 32 30 31 35 2d
00000e0 30 32 2d 31 36 54 31 36 3a 35 38 3a 30 38 5a 2c
00000f0 34 33 2e 39 30 31 34 38 2c 31 30 2e 32 32 30 31
0000100

文件的前两行

UNIX TIME,TIME,LAT,LONG,ALT,DIST,HR,CAD,TEMP,POWER
1424105808,2015-02-16T16:56:48Z,43.8964,10.22444,0.87,0,0,0,No Data,No Data

更新好像是\r。我不知道为什么它没有更早地工作,但我在探索时学到了一些东西。谢谢大家的帮助。

【问题讨论】:

  • 对这个问题"How can I read and parse CSV files in C++?" 的回答是否有任何帮助?
  • 我已经通读了它们,虽然它们正在解决我所说的问题,但我不知道该怎么做。
  • 假设您的文件与描述的一样简单。您的代码看起来应该是正确的。因此,总而言之,您是说while (getline(inFile, line)) 击中 once 并啜饮 everything ?这是在什么平台上运行的?
  • 如果可能,请不要使用图片,尤其是如果可以使用 hexdump 作为文本进行演示。只需打开一个控制台并在问题中粘贴hexdump -n 256 filename 作为源列表可能就足够了,假设第一行不超过 256 个字节。看起来something like this 是您问题的一个很好的补充。前几行的实际文本也会很好。
  • 谢谢,最后,请包含文件中的前两行实际文本。 while循环命中一次似乎很奇怪。您已经确认data一个条目,对吧? (我知道,这似乎是一个多余的问题,但必须问)。从该转储的外观来看,分隔符是0x0D'\r' only。你说你尝试将外部 getline 更改为 std::getline(inFile, line, '\r')

标签: c++ parsing csv eol


【解决方案1】:

一个简单的解决方法是编写自己的getline
例如,忽略 \n,\r 的任意组合
在行的开头,并且也中断了。
这适用于任何平台,但不会保留空行。

查看十六进制转储后,分隔符为0d (\r)

【讨论】:

    【解决方案2】:

    您是否尝试将\r\n 的顺序切换为\n\r

    【讨论】:

    • 是的,我已经切换了它们。事实证明 getline() 只接受一个字符作为分隔符。因此,它们都不是有效的并且都会导致错误。
    • Getline 有一个分隔符选项,对吧?也许用那个?
    • 分隔符选项只需要一个字符。
    • 它没有。该问题列出了我尝试过的组合。
    • \n\r 不是任何计算机系统上的行终止符。这个建议是徒劳的。有关背景信息,请参阅 here
    猜你喜欢
    • 2016-06-25
    • 2016-01-10
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    相关资源
    最近更新 更多