如何在C++中读取包含引号的CSV文件?
处理带引号的CSV文件(C++新手友好实现)
嘿,作为C++新手碰到带引号的CSV确实有点头疼——毕竟标准的逗号分割逻辑会被引号里的内容直接打乱!我来给你一步步拆解怎么搞定这个需求,让你能正确读取"Mary", "000111222", "Junior", 12, 4.0这种格式的CSV,还能原样输出。
核心思路
带引号的CSV关键在于:只有不在引号包裹范围内的逗号才是字段分隔符。所以我们需要逐行读取文件,然后逐个字符扫描,跟踪当前是否处于引号内部,以此来判断什么时候分割字段。
完整实现代码
下面是可以直接跑的代码,我加了详细注释,方便你理解每一步:
#include <iostream> #include <fstream> #include <string> #include <vector> #include <cctype> // 用于isdigit判断 // 解析一行带引号的CSV,返回所有字段的列表 std::vector<std::string> parseQuotedCSVLine(const std::string& line) { std::vector<std::string> fields; std::string currentField; bool inQuotes = false; // 标记当前是否处于引号内部 for (char c : line) { if (c == '"') { // 遇到引号就切换状态:从非引号区进引号区,或者反过来 inQuotes = !inQuotes; // 如果需要保留字段前后的引号,就把这行改成 currentField += c; } else if (c == ',' && !inQuotes) { // 只有不在引号里的逗号才是分隔符,保存当前字段并重置 fields.push_back(currentField); currentField.clear(); } else { // 普通字符直接加入当前字段 currentField += c; } } // 把最后一个字段加入列表(因为最后没有逗号) fields.push_back(currentField); // 处理字段前后的空格(你的示例里逗号后有空格,比如", ") for (auto& field : fields) { // 去掉开头的空格 size_t startPos = field.find_first_not_of(" "); if (startPos != std::string::npos) { field = field.substr(startPos); } // 去掉结尾的空格 size_t endPos = field.find_last_not_of(" "); if (endPos != std::string::npos) { field = field.substr(0, endPos + 1); } } return fields; } int main() { // 替换成你的CSV文件名 std::ifstream inputFile("students.csv"); if (!inputFile.is_open()) { std::cerr << "错误:无法打开文件!" << std::endl; return 1; } std::string line; // 逐行读取文件 while (std::getline(inputFile, line)) { auto fields = parseQuotedCSVLine(line); // 按照输入格式输出字段 for (size_t i = 0; i < fields.size(); ++i) { // 判断字段是否需要加引号:简单规则——非数字字段加引号 bool isNumeric = true; for (char c : fields[i]) { if (!isdigit(c) && c != '.') { isNumeric = false; break; } } if (!isNumeric) { std::cout << "\"" << fields[i] << "\""; } else { std::cout << fields[i]; } // 不是最后一个字段的话,输出分隔符", " if (i != fields.size() - 1) { std::cout << ", "; } } std::cout << std::endl; } inputFile.close(); return 0; }
关键细节说明
- 引号状态跟踪:
inQuotes变量是核心,确保我们不会把引号内部的逗号当成分隔符。 - 空格处理:示例里的CSV是
", "格式,所以加了trim逻辑去掉字段前后的空格,避免输出时出现多余空格。 - 输出引号判断:用简单的“是否是数字”来区分要不要加引号,如果你有更明确的规则(比如原输入里固定某几列是字符串),可以直接修改这个判断逻辑。
进阶提示
如果之后你需要处理更复杂的CSV(比如引号里包含逗号、转义引号""),手动解析会变得很繁琐,这时候可以用成熟的第三方CSV库,比如fast-csv-parser,不过作为新手,先把手动解析的逻辑搞懂,能帮你更好理解CSV的本质哦~
内容的提问来源于stack exchange,提问作者Brody Gore
相关产品推荐
相关产品推荐

