一、读文件:永远只用 getline
不要用 >>运算符(遇到空格就停),CSV 处理唯一的标准答案是按行读取。
std::ifstream file("data.csv"); std::string line; while (std::getline(file, line)) { // line 就是 CSV 的一整行 }为什么要这么做?
因为 CSV 的逻辑单位是“行”,getline天然契合这种数据结构,且不用担心空格问题。
二、切分字符串:手写一个“查找-截取”循环
这是最核心的一步。不要用 stringstream(慢且笨重),直接操作字符串下标。
std::vector<std::string> split(const std::string& line) { std::vector<std::string> res; size_t start = 0, end; while ((end = line.find(',', start)) != std::string::npos) { res.push_back(line.substr(start, end - start)); start = end + 1; } res.push_back(line.substr(start)); // 别忘了最后一段 return res; }逻辑拆解:http://www.wx-tong.com/
-
find(',', start):从start位置开始找下一个逗号。 -
substr(start, length):截取两个逗号之间的内容。 - 循环直到找不到逗号为止。
三、组装:两行代码处理一行数据
有了上面两个工具,主逻辑会变得非常干净。
while (std::getline(file, line)) { auto cols = split(line); // 切分 std::cout << cols[0] << "\n"; // 使用第一列数据 }四、避坑指南(必看)
1. 处理 Windows 换行符
Windows 的换行符是 \r\n,Linux 是 \n。如果不处理,\r会残留在字符串末尾。
修复方法:
在 getline之后加一句:
if (!line.empty() && line.back() == '\r') line.pop_back();2. 处理引号包裹的内容(进阶)
如果遇到 "Hello,World"这种带逗号的单元格,简单的 find(',')会失效。此时需要判断引号状态(进阶内容,初学可先略过,只需知道有这个坑)。
五、总结
C++ 处理 CSV 的万能公式:
**
ifstream+ getline负责“拿进来”,
find+ substr负责“拆开来”。**
这套方案不依赖任何第三方库,代码量少,逻辑直观,足以应付 80% 的日常开发需求。