使用std::cout输出类成员变量时出现不一致结果的问题排查
问题原因与解决方案
核心问题根源
你的CSV文件每行末尾带有Windows风格的回车符(\r),而std::getline读取行时只会移除换行符\n,导致line字符串末尾残留了\r。这个隐藏的控制字符就是输出异常的元凶。
为什么两种输出表现不同
- 分开输出正常:每个字段输出后都加了
\n强制换行,\r带来的光标回退行为被换行抵消,所以看不到异常。 - 合并输出异常:以
date字段为例,它的实际内容是"4/14/23\r"。当std::cout输出这个字符串时,\r会让控制台光标跳回当前行开头,后续输出的" , "会覆盖掉date的前几个字符,最终只留下date的最后一个字符3没被完全覆盖,就出现了你看到的", NONE3 , SQ *SIPPY CAFE, -6.99"这种错位结果。
修复方案
只需要在读取行或解析字段时清理残留的\r即可,两种方法任选其一:
方法1:读取行时直接清理
修改main函数中的读取逻辑:
while(getline(file, line)) { // 移除行末尾可能存在的\r if (!line.empty() && line.back() == '\r') { line.pop_back(); } if (line[0] == '4') { // 保留你的筛选逻辑 CSVRow row = CSVRow(line); row.setPayee(payee_map); rows.push_back(row); } }
方法2:解析字段时清理
修改SplitRow函数中的token处理:
std::vector<std::string> SplitRow(std::string& unsplit_row, const char& delim) { std::istringstream stream(unsplit_row); std::string token; std::vector<std::string> row; while(getline(stream, token, delim)) { // 移除token末尾的\r if (!token.empty() && token.back() == '\r') { token.pop_back(); } row.push_back(token); } return row; }
验证效果
修复后,合并输出的printRow方法就能正常显示所有字段,不会再出现错位和内容覆盖的问题。
内容的提问来源于stack exchange,提问作者Christian Opperman
相关产品推荐
相关产品推荐

