You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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;
}

关键细节说明

  1. 引号状态跟踪:inQuotes变量是核心,确保我们不会把引号内部的逗号当成分隔符。
  2. 空格处理:示例里的CSV是", "格式,所以加了trim逻辑去掉字段前后的空格,避免输出时出现多余空格。
  3. 输出引号判断:用简单的“是否是数字”来区分要不要加引号,如果你有更明确的规则(比如原输入里固定某几列是字符串),可以直接修改这个判断逻辑。

进阶提示

如果之后你需要处理更复杂的CSV(比如引号里包含逗号、转义引号""),手动解析会变得很繁琐,这时候可以用成熟的第三方CSV库,比如fast-csv-parser,不过作为新手,先把手动解析的逻辑搞懂,能帮你更好理解CSV的本质哦~

内容的提问来源于stack exchange,提问作者Brody Gore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:33:44