我在处理 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
Sale,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
我遇到的问题是,由于某些奇怪的原因,在逗号分隔处理单词 “Sale”
的每 5 个标记后,会覆盖单词 Value
,我无法理解为什么。非常感谢一些指导。
最佳答案
根据描述(但在引用的文本中不可见),每一行都以 '\r'
开头(回车)字符。一些系统使用行尾序列。 Windows 通常使用 "\r\n"
(回车,换行)将被单个 '\n'
取代在非 binary
中打开文件时模式(即,在创建流时不传递标志 std::ios_base::binary
时)。但是,对于“\n\r”序列,不会发生这种替换。
您可以通过替换所有 '\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";
神奇的是添加了<< std::ws
在读取仅删除所有前导空格的行时。该代码还删除了 inappropriate use of std::endl
.如果每行的第一个单词可能包含前导空格,则您需要采用不同的方法,可能会删除 '\r'
创建前的字符 linestream
,例如,使用
line.erase(std::remove(line.begin(), line.end(), '\r'), line.end());
关于c++ - 使用 getline 的 csv 处理行为不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27117872/