使用getline进行csv处理的行为不明确

时间:2014-11-25 02:34:29

标签: c++

我在处理csv文件时遇到了一些问题。我是C ++的新手并且正在努力学习。这可能是我忽略的一件小事,但我在网上搜索了答案,无法弄清楚我哪里出错了。我正在尝试处理一个具有多行和逗号分隔值的文件(虽然这会产生影响但在行尾没有逗号) - 请注意,当我尝试发布文本时,它不包括段落,我不得不手动添加 - 不确定是否有所作为

  

Sale,11/9 / 14,11 / 9/14,AMAZON MKTPLACE PMTS,-8.99

     

Sale,10/4 / 14,10 / 5/14,AMAZON MKTPLACE PMTS,-13.08

     

Sale,10/3 / 14,10 / 5/14,AMAZON MKTPLACE PMTS,-9.82

     

Sale,10/2 / 14,10 / 3/14,AMAZON MKTPLACE PMTS,-45.48

     

Sale,8/21 / 14,8 / 22/14,AMAZON MKTPLACE PMTS,-9.99

     

销售,11/8 / 14,11 / 9/14,Amazon.com,-64.7

     

Sale,10/1 / 14,10 / 2/14,APL * ITUNES.COM/BILL,-1.08

     

Sale,9/15 / 14,9 / 16/14,APL * ITUNES.COM/BILL,-1.08

我尝试使用getline将每一行放入stringstream,然后使用以下代码用逗号分隔符解析每一行:

ifstream file("test1.csv"); 
string value, line;
while (getline(file, line)) {
    stringstream   linestream(line);
    while (getline(linestream, value, ',')) {
        cout << "Value:   " << value << endl;
    } // while
    cout << "Done Procesing" << endl;
} // while

我得到的问题是,由于一些奇怪的原因,在逗号分隔处理后的每个第5个标记处,单词“Sale”会覆盖单词Value,我无法理解为什么。非常感谢一些指导。

1 个答案:

答案 0 :(得分:2)

根据描述(但在引用的文字中不可见),每一行以'\r'(回车)字符开头。一些系统使用行结束序列。 Windows通常使用"\r\n"(回车符,换行符),当以非'\n'模式打开文件时(即未传递标记{{}时)将被单个binary替换。 1}}创建流时)。但是,对于“\ n \ r”序列,此替换不会发生

您可以在创建std::ios_base::binary之前替换所有'\r'字符轻松验证此理论(我在那里放了一个额外的std::istringstream因为我看不出为什么读/写流应该创建):

i

有了这个改变,我希望除了第一行之外的所有字的输出看起来像这样:

std::transform(line.begin(), line.end(), line.begin(), '\r', '@');
std::istringstream linestream(line);

解决问题的最简单方法是在阅读该行时简单地跳过前导空格。相应的代码摘录如下所示:

Value:   @Sale

魔术是在读取简单删除所有前导空格的行时添加std::ifstream file("test1.csv"); for (std::string line; std::getline(file << std::ws, line); ) { std::istringstream linestream(line); for (std::string value; std::getline(linestream, value, ','); ) { std::cout << "Value: " << value << '\n'; } // for } std::cout << "Done Procesing\n"; 。该代码还会删除inappropriate use of std::endl。如果每行上的第一个单词可能包含前导空格,则需要采用不同的方法,可能会在创建<< std::ws之前删除'\r'个字符,例如,使用

linestream