17370845950

c++中如何分割字符串_c++ split字符串实现代码【源码】
std::string无内置split函数;C++20的split_view是只读视图,需手动提取;常用方法有:stringstream(单字符分隔符)、find+substr(多字符分隔符)、regex_split(正则,性能差);复杂场景应使用专用解析库。

std::string 没有内置 split 成员函数

这是 C++ 初学者最容易困惑的一点:std::string 本身不提供 split() 方法。C++20 虽引入了 std::ranges::split_view,但它是视图、不可直接生成 std::vector<:string>,且需配合迭代器手动提取,实用性受限。实际项目中仍普遍依赖手写或标准库组合实现。

用 std::stringstream 按空格/单分隔符分割最简洁

适用于分隔符固定(如空格、制表符、逗号)且不含嵌套或转义的场景,代码短、可读性强、无额外依赖:

std::vector split(const std::string& s, char delim) {
    std::vector tokens;
    std::string token;
    std::istringstream tokenStream(s);
    while (std::getline(tokenStream, token, delim)) {
        if (!token.empty()) tokens.push_back(token); // 跳过连续分隔符产生的空串
    }
    retur

n tokens; }

注意:std::getline 默认以换行符为界,传入第三个参数 delim 才按指定字符切;连续分隔符(如 "a,,b")会产出空字符串,需显式过滤。

用 find + substr 实现多字符分隔符(如 " | " 或 "::")

当分隔符是子字符串(非单字符)时,std::stringstream 无法胜任,必须用 find()substr() 手动扫描:

  • std::string::find() 返回首个匹配位置,没找到返回 std::string::npos
  • 每次从上一个结束位置开始找下一个分隔符,用 substr(start, length) 提取子串
  • 需处理末尾无分隔符的情况:最后一次提取应到字符串末尾,而非依赖 find() 成功

典型实现:

std::vector split(const std::string& s, const std::string& delim) {
    std::vector tokens;
    size_t start = 0, end = 0;
    while ((end = s.find(delim, start)) != std::string::npos) {
        tokens.push_back(s.substr(start, end - start));
        start = end + delim.length();
    }
    tokens.push_back(s.substr(start)); // 剩余部分
    return tokens;
}

regex_split 性能差、编译慢,慎用于高频或嵌入式场景

std::regex 支持任意正则分隔符(如 "\\s+""[;,]\\s*"),但代价明显:

  • 编译期开销大:正则表达式对象构造耗时,尤其在循环内反复创建
  • 运行时慢:比手工扫描慢数倍,std::regex_iterator 内部状态复杂
  • MSVC 和 libstdc++ 的 std::regex 实现长期存在 bug 或不完整(如不支持某些断言)

仅当分隔逻辑真正需要正则能力(例如“跳过引号内的逗号”)时才考虑,否则优先用前两种方法。

真正难的是分隔符有上下文依赖(比如 CSV 解析、带转义的 JSON 字符串切分),那种情况别硬写 split,直接用成熟 parser 库更稳妥。