C++字符串分割
字符串分割是编程中经常遇到的一个问题,采用C++语言实现字符串分割与其他语言有所不同,下面将采用C++语言实现字符串分割并对用到的字符串操作函数进行详细的描述。
字符串分割Java实现
Java通过调用String.split(String delimiter)方法可直接完成对字符串的分割。
1
2
3
4
5
6
7public static void main(String[] args){
String str = "I am a good programmer!";
String[] splited_string = str.split(" ");
for(String s : splited_string){
System.out.println(s);
}
}字符串分割Python实现
python实现字符串分割代码更为间接,很多功能使用python实现仅用一行代码,江湖上称之为“一行流”。
1
print("I am a good programmer!".split(" "))
字符串分割C++实现
比起Java和python实现,采用C++实现字符串分割的过程则略为繁琐。需要用到c_str()、strcpy()、strtok()等方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using namespace std;
void splitString(const string &str, const string &split, vector<string> &res)
{
// str:要处理的字符串
// split:分隔符
// res:存放分割后的结果
char *strc = new char[str.size() + 1];
strcpy(strc, str.c_str());
char *temp = strtok(strc, split.c_str());
//strtok()的源码为char *__cdecl strtok(char * __restrict__ _Str,const char * __restrict__ _Delim)
//strtok接收的参数时char*类型,因此进行字符串分割前需要将string类型的字符串转为char*类型
while (temp != NULL)
{
res.push_back(string(temp));
temp = strtok(NULL, split.c_str()); //strtok第一个参数传入NULL,使用之前保存的SAVE_PTR定位下一个待处理的字符的位置
}
delete[] strc;
}
int main(){
vector<string> result;
splitString("I am a good programmer!", " ", result);
cout << "分割的子字符串的数量为:" << result.size() << endl;
cout << "分割后的字符串为:" << endl;
for(int i = 0; i < result.size(); ++i) {
std::cout << result[i] << endl;
}
return 0;
}字符串分割所使用方法详解
string.c_str()
c_str()方法的原型如下:
1
const _CharT* c_str()
该方法返回一个指向常量的指针,指针所指向的内容不能被修改,在字符串分割中主要使用该方法将string类型转为char*类型,与字符串分割函数strtok()方法的接收参数类型保持一致。注意:一定要使用strcpy()函数等来操作方法c_str()返回的指针。
string.strcpy()
strcpy()方法的原型如下:
1
char * __cdecl strcpy(char * __restrict__ _Dest,const char * __restrict__ _Source);
该方法将字符串Source复制到Dest。该方法线程不安全,c++提供了线程安全的字符串拷贝方法strcpy_s()。
string.strtok()
strtok()方法的原型如下:
1
char *__cdecl strtok(char * __restrict__ _Str,const char * __restrict__ _Delim)
其中,Str表示要进行分割的字符串,Delim为字符串分隔符,该方法将Delim中的字符作为分隔符对字符串Str进行分割。如果Str为空,则函数内部的SAVE_PTR指针在下一次调用中将作为下一个分割字符串的起始位置。其实这就说明在函数strtok()内部使用了一个静态变量SAVE_PTR指针,用以记录分割一次之后_String中下一个字符串的位置。这种方法导致了一个问题,就是strtok()函数是线程不安全的(因为其函数内部使用到了静态存储区)。
除此之外,从函数的定义,第一个传入参数_String定义为char*而不是const char*,就说明strtok()函数不保证不修改传入数据的内容。实际上,第一个参数_String传进来的字符串,是会被strtok()函数所修改的,因此调用strtok()函数的时候应当注意。
c++中也提供了线程安全的字符串分割方法strtok_s,其原型如下:
1
char *__cdecl strtok_s(char *_Str,const char *_Delim,char **_Context);
strtok_s()函数增加了一个参数_Context,这个参数就是相当于strtok()函数中内部定义的静态SAVE_PTR指针,用来传递对字符串_String的处理进行到了哪里。