读取CSV文件时如何避免逗号空格误触发getline()停止读取?
CSV字段拆分错误修复方案
问题本质
你当前的实现直接将所有逗号作为getline的分割终止符,没有遵循CSV的基础规则:被双引号包裹的字段内部的逗号属于字段内容,不能作为分割依据,才会把示例中title字段内部的逗号误判成分隔符,导致后续所有字段错位。
刚好你提到的「合法分隔逗号后均为字母、字段内部逗号后为空格」的特征,可以用来快速修复逻辑,无需引入额外依赖。
方案1:按现有特征定制解析逻辑(无第三方依赖)
核心逻辑:先读取完整行,逐字符遍历判断:仅当逗号不在双引号包裹范围内、且逗号后第一个非空字符为字母时,才判定为合法字段分隔符。
示例代码如下:
#include <string> #include <vector> #include <cctype> // ... 其他已有代码 std::string line; while (std::getline(excel_file, line)) { std::vector<std::string> fields; std::string current_field; bool in_quote = false; int line_len = line.size(); for (int i = 0; i < line_len; ++i) { char cur_char = line[i]; // 处理双引号标记 if (cur_char == '"') { in_quote = !in_quote; // 若不需要保留字段两端的双引号可取消注释下一行 // continue; } // 仅非引号内的逗号才可能是分隔符 if (!in_quote && cur_char == ',') { // 找到逗号后第一个非空格字符 int next_valid_pos = i + 1; while (next_valid_pos < line_len && std::isspace(line[next_valid_pos])) { next_valid_pos++; } // 逗号后第一个非空字符是字母,判定为合法分隔符 if (next_valid_pos < line_len && std::isalpha(line[next_valid_pos])) { fields.push_back(current_field); current_field.clear(); i = next_valid_pos - 1; // 跳过中间的空格 continue; } } current_field += cur_char; } // 加入最后一个字段 fields.push_back(current_field); // 字段数校验后赋值给book对象 if (fields.size() == 5) { book.set_isbn(fields[0]); book.set_title(fields[1]); book.set_author(fields[2]); book.set_genre(fields[3]); book.set_year_published(fields[4]); } }
方案2:通用CSV解析(适配后续规则变动)
如果后续CSV的字段规则可能调整(比如字段内出现逗号后接字母的情况),可以直接使用成熟的轻量CSV解析库,无需自己处理所有边界情况,仅需几行代码即可完成字段读取。
内容的提问来源于stack exchange,提问作者qu4lizz
相关产品推荐
相关产品推荐

