CSV解析器适用于Windows,而不适用于Linux

时间:2011-02-20 22:42:47

标签: c++ linux csv

我正在解析一个如下所示的CSV文件:

E1,E2,E7,E8,,,
E2,E1,E3,,,,
E3,E2,E8,,,
E4,E5,E8,E11,,,

我将每行中的第一个条目存储在一个字符串中,其余的都存入一个字符串向量:

while (getline(file_input, line)) {
    stringstream tokenizer; 
    tokenizer << line;
    getline(tokenizer, roomID, ',');
    vector<string> aVector;
    while (getline(tokenizer, adjRoomID, ',')) {
        if (!adjRoomID.empty()) {
            aVector.push_back(adjRoomID);
        }
    }
    Room aRoom(roomID, aVector);
    rooms.addToTail(aRoom);
}

在Windows中,这很好用,但是在Linux中,每个向量的第一个条目神秘地丢失了第一个字符。例如,在第一次迭代中通过while循环:

roomIDE1aVector2 E7 E8

然后是第二次迭代: roomIDE2aVector1 E3

注意aVector第一个条目中缺少的E。

当我输入一些调试代码时,它似乎最初正确地存储在向量中,但随后会覆盖它。感谢任何想出这个的人。对我来说似乎很奇怪。

修改 谢谢Erik。我终于明白了。在Windows上,所有行都以\ n结尾。当我切换到Unix \ Linux时,行以\ r \ n结尾。因此,当getline读取一行时,它会将所有内容读入包含\ r的字符串中。我没有考虑到这个\ r \ n它让我搞砸了。问题不在于E缺失了。这是我在向量中有一个额外的条目,其中包含一个\ r \ n字符。我的其他类无法使用单个\ r来处理此条目。

3 个答案:

答案 0 :(得分:3)

哎呀:误读了你的问题,认为它是在谈论不在 Windows 上工作。我在这里留下答案以防万一有人因此而发现需要它,但我不认为在这种情况下它会帮助你(提问者)。

如果您使用的是MSVC6,则可能会遇到使用getline函数的this bug。链接中有一个修复程序。

对于后代,这是来自链接的信息:

  

症状:“标准C ++库模板   getline函数读取额外的   遇到后的角色   分隔符。请参考样本   更多信息中的程序   部分详情。“

     

修改getline成员函数,   可以在以下找到   系统头文件字符串,如下:

else if (_Tr::eq((_E)_C, _D))
            {_Chg = true;
          //  _I.rdbuf()->snextc(); /* Remove this line and add the line below.*/ 
              _I.rdbuf()->sbumpc();
            break; }
  

注意:因为解决方案涉及   修改系统头文件,   应该极其小心以确保   没有别的东西在改变了   头文件。微软不是   对由此产生的任何问题负责   从不必要的变化到系统   头文件

答案 1 :(得分:2)

我怀疑windows \ r \ n换行中的\ r \ n可能会弄乱你打印的代码。

如果更改为此if语句,问题是否会消失?

if (!adjRoomID.empty() && (adjRoomID[0] != '\r'))

编辑:修正了拼写错误

答案 2 :(得分:0)

尝试一些cout调试。在阅读时打印出值:

if (!adjRoomID.empty()) {
    cout << '"' << adjRoomId << '"' << endl;
    aVector.push_back(adjRoomID);
}

这将告诉您是否从一开始就正确读取了您的字符串,并且还可能会告诉您是否正在从文件中读取额外的奇怪字符。