C++ 按自定义分隔符分割字符串
C++ 基于stringstream按自定义分隔符分割字符串(进阶用法)
一、核心知识点总结
1. 【重点】核心实现逻辑
使用std::stringstream结合std::getline,通过指定自定义分隔符(如逗号、分号、竖线)拆分字符串,核心流程如下:
- 将待分割字符串传入
stringstream,构建字符串流对象; - 循环调用
std::getline读取流内内容,读取至指定分隔符时停止; - 可选过滤空字符串,用于处理连续分隔符(如
a,,b)、首尾分隔符(如,a,b,)的特殊场景。
2. 核心组件与函数
- 存储容器:
std::vector<std::string>,用于存放分割后的所有子串; - 流载体:
std::stringstream,将普通字符串封装为流,支持流式读写操作; - 读取工具:
std::getline,核心读取函数,支持自定义分隔符,是实现灵活分割的关键。
3. 【备注】边界场景处理
- 空字符串:若传入待分割字符串为空,分割后返回空的
vector; - 连续分隔符:通过
!token.empty()判断可过滤空串,例如a;;b分割后仅保留a、b; - 首尾分隔符:若字符串以分隔符开头或结尾(如
;a;b;),会生成空串,需根据业务需求决定是否过滤。
4. 性能与适用场景
- 优势:代码简洁、可读性强,对于中小规模字符串,性能优于手动遍历字符的方式;
- 局限:处理超大字符串时,建议使用
std::string::find手动实现分割,可减少流对象的内存与性能开销。
5. 【重点】扩展能力
分割得到的字符串子串,可通过嵌套std::stringstream直接转换为int、float、double等数值类型,无需额外编写解析逻辑。
二、核心函数参数与功能列表
| 函数名 | 参数 | 功能描述 |
|---|---|---|
std::stringstream | const std::string& str | 构造函数:将传入的字符串封装为字符串流对象,支持流的输入与输出操作 |
std::getline | std::istream& is | 读取流参数:指定要读取的输入流(可传入stringstream对象) |
std::getline | std::string& str | 存储参数:将读取到的子串存入该字符串变量中 |
std::getline | char delim | 分隔符参数:设定分割终止字符(如,、;、` |
std::vector::push_back | const std::string& val | 容器操作:将分割后的有效子串添加至vector末尾,保存最终分割结果 |
std::string::empty | 无 | 判空函数:检查分割得到的子串是否为空,用于过滤无效空串 |
std::stringstream | const std::string& token | 类型转换:将字符串子串封装为流,用于后续数值类型转换 |
operator>> | std::stringstream& ss | 流提取符:从字符串流中提取数据,支持基础数据类型的转换 |
operator>> | int& num | 数值存储:将流中字符串转换为int类型,并存入该变量 |
operator>> | float& num | 数值存储:将流中字符串转换为float类型,并存入该变量 |
三、基础示例:按自定义分隔符分割字符串
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
std::vector<std::string> splitByDelimiter(const std::string& str, char delimiter) {
std::vector<std::string> result;
std::stringstream ss(str);
std::string token;
while (std::getline(ss, token, delimiter)) {
if (!token.empty()) {
result.push_back(token);
}
}
return result;
}
int main() {
std::string test_str = "C++;Java;;Python,Go";
auto parts_semicolon = splitByDelimiter(test_str, ';');
std::cout << "按分号分割结果:" << std::endl;
for (const auto& part : parts_semicolon) {
std::cout << part << std::endl;
}
auto parts_comma = splitByDelimiter(test_str, ',');
std::cout << "\n按逗号分割结果:" << std::endl;
for (const auto& part : parts_comma) {
std::cout << part << std::endl;
}
return 0;
}
输出结果
按分号分割结果:
C++
Java
Python,Go
按逗号分割结果:
C++;Java;;Python
Go
四、扩展示例:分割后转换为数值类型
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
std::vector<int> splitToInt(const std::string& str, char delimiter) {
std::vector<int> result;
std::stringstream ss(str);
std::string token;
while (std::getline(ss, token, delimiter)) {
if (!token.empty()) {
int num;
std::stringstream(token) >> num;
result.push_back(num);
}
}
return result;
}
int main() {
std::string num_str = "10,25,30,,45";
auto nums = splitToInt(num_str, ',');
std::cout << "分割并转换为整数结果:" << std::endl;
for (int num : nums) {
std::cout << num << " ";
}
return 0;
}
输出结果
分割并转换为整数结果:
10 25 30 45
五、使用注意事项
- 【备注】
std::getline读取时不会包含分隔符本身,需注意分割后子串的完整性; - 【备注】 数值转换时,若子串非合法数值(如
abc转int),会导致转换失败,可添加异常处理增强鲁棒性; - 【备注】 该方法依赖
<sstream>头文件,使用前需确保引入对应头文件。