C++ 常见问题:字符串分割
在一些编程练习中,经常会对字符串进行处理,往往处理之前都会对字符串进行分割来提取各部分信息。在C++中虽然没有像python那样提供split这样直接的字符串分割函数,但也有一些其他的方法能够对其进行分割,下面介绍几种C++中常用的字符串分割方法。
方法一:通过 string 成员函数实现#
-
find() 函数
- 原型: size_t find (const string& str, size_t pos = 0) const;
- 功能:查找子字符串第一次出现的位置。
- 参数说明:str为子字符串,pos为初始查找位置。
- 返回值:找到的话返回第一次出现的位置,否则返回string::npos。
-
substr()函数:
- 原型: string substr (size_t pos = 0, size_t len = npos) const;
- 功能:在原字符串中截取子字符串。
- 参数说明:pos为起始位置,len为要截取子字符串的长度。
- 返回值:子字符串。
vector<string> split(const string &str, const string &pattern)
{
vector<string> res;
if(str == "")
return res;
//在字符串末尾也加入分隔符,方便截取最后一段
string strs = str + pattern;
size_t pos = strs.find(pattern);
while(pos != strs.npos)
{
string temp = strs.substr(0, pos);
res.push_back(temp);
//去掉已分割的字符串,在剩下的字符串中进行分割
strs = strs.substr(pos+1, strs.size());
pos = strs.find(pattern);
}
return res;
}
vector<string> split(const string& str, const string& pattern)
{
size_t pos1, pos2;
pos2 = str.find(pattern);
pos1 = 0;
vector<string> result;
while(npos != pos2)
{
result.push_back(str.substr(pos1, pos2-pos1));
pos1 = pos2 + pattern.size(); // 跳过模式串
pos2 = str.find(pattern, pos1);
}
if(pos1 != str.length())
result.push_back(str.substr(pos1));
return result;
}
方法二:通过 strtok 函数实现#
- strtok为C语言中的字符串分割函数,其具体解释如下:
- 原型:char * strtok ( char * str, const char * delimiters );
- 功能:分割字符串str,delimiters为指定的分割符,可以有多个。
- 说明:strtok只能接受 C 风格的字符串,如果是 string 类型,可以使用 c_str 函数进行转换。strtok() 用来将字符串分割成一个个片段。参数s指向欲分割的字符串,参数delim则为分割字符串,当strtok()在参数s的字符串中发现到参数delim的分割字符时 则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。每次调用成功则返回被分割出片段的指针。
vector<string> split(const string &str, const string &pattern)
{
char * strc = new char[strlen(str.c_str())+1];
strcpy(strc, str.c_str()); //string转换成C-string
vector<string> res;
char* temp = strtok(strc, pattern.c_str());
while(temp != NULL)
{
res.push_back(string(temp));
temp = strtok(NULL, pattern.c_str());
}
delete[] strc;
return res;
}
方法三:通过 stringstream 实现#
- stringstream 为字符串输入输出流,继承自iostream,灵活地使用 stringstream 流可以完成很多字符串处理功能,例如字符串和其他类型的转换,字符串分割等。在这里,我们使用其实现字符串分割功能。注意 stingstream 的使用需要包含 sstream 头文件。
vector<string> split(const string &str, const char pattern)
{
vector<string> res;
stringstream input(str); //读取str到字符串流中
string temp;
// 使用 getline 函数从字符串流中读取,遇到分隔符时停止,和从 cin 中读取类似
// 注意, getline 默认是可以读取空格的
while(getline(input, temp, pattern))
res.push_back(temp);
return res;
}
方法四:通过 boost 库中的 split 函数#
boost库有很多方法来实现split,也包含了一个split函数,可以直接使用,非常实用而且强大,但是得自己下载boost库。使用代码如下
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
using namespace boost;
void print( vector <string> & v )
{
for (size_t n = 0; n < v.size(); n++)
cout << "\"" << v[ n ] << "\"\n";
cout << endl;
}
int main()
{
string s = "a,b, c ,,e,f,";
vector <string> fields;
cout << "Original = \"" << s << "\"\n\n";
cout << "Split on \',\' only\n";
split( fields, s, is_any_of( "," ) );
print( fields );
cout << "Split on \" ,\"\n";
split( fields, s, is_any_of( " ," ) );
print( fields );
cout << "Split on \" ,\" and elide delimiters\n";
split( fields, s, is_any_of( " ," ), token_compress_on );
print( fields );
return 0;
}
输出结果:
Original = "a,b, c ,,e,f,"
Split on ',' only
"a"
"b"
" c "
""
"e"
"f"
""
Split on " ,"
"a"
"b"
""
"c"
""
""
"e"
"f"
""
Split on " ," and elide delimiters
"a"
"b"
"c"
"e"
"f"
""
在C++中还有很多方法来实现split 函数,cplusplus.com有个C++ split 专题,详细比较分析了几种实现方法(见下图)。链接见文末参考文献。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通