[C++杂记] string串切分
2015-03-09 09:02
155 查看
在做LeetCode上面的Compare Version Number时,需要对所需要的串进行分割操作。对字符串的切分操作也是很常规的一种操作。
本文介绍使用函数strtok及其衍生函数来对字符串进行切分。
传入参数:str 目标字符串,待分割的字符串
delimiters 分隔符字符串。由于是一个字符串,而不是一个字符,因此可以在一次分割过程中同时使用多个分隔符对str进行分割
返回值 :返回值是char*,并不是char**。因此仅仅使用一次该函数并不能得到分割后的结果。
使用模板如下所示:
运行结果为:
ptr=ab
ptr=cd
ptr=ef
对该模板的解释:
1、由于返回值是一个char*类型,故对strtok函数的一次调用只可以得到目标字符串str的一个分割后的子串。必须通过循环不断地得到其分割后的子串。
2、第3行和第7行是在写while循环中的固定模板,第3行是初始化循环变量,第7行是改变循环变量。在使用strtok函数中,第7行中第一个参数是NULL。
3、分隔符字符串包含两个字符,从运行结果中可以看出,在逗号和冒号处都进行了分割。
4、该函数支持空格分隔符。
ptr=1
ptr1=11
ptr=22
ptr1=33
对上述代码和结果的解释:
strtok函数在对待分割的字符串进行分割时,将分割后的中间结果保存在一个静态变量中,该静态变量对于用户来说是隐藏的,是该函数自动创建的辅助变量。假设该变量名为temp。运行至第6行时,temp中的值为第一次分割完str之后的结果“0”。运行至第7行时,temp中的值为第一次分割完str1之后的结果“22.33”。进入while循环之后,第一次运行第13行时,由于temp中的值是“22.33”,因此分割完之后得到的结果为“22”。接着运行第14行,得到“33”。
这种现象是由于函数strtok使用了没有加锁的静态变量,当多个线程同时访问这个变量时,结果就会不可控。最简单的解决方案就是为不同的进程开辟不同的变量,用来分别保存各自的中间结果。
在windows中,strtok_s函数实现了上述功能;在Linux中,相应的升级版函数为strtok_r。他们的函数原型分别为:
char *strtok_s( char *strToken, const char *strDelimit, char **buf);
char *strtok_r(char *str, const char *delim, char **saveptr);
第3个参数为代替静态变量的用于存储中间结果的变量。如下为使用strtok_r函数的模板:
ptr=1
ptr1=11
ptr=0
ptr1=22
strtok的缺点:
1、strtok会将还没有进行分割的字符串存储在中间辅助变量中,如果同时使用多个strtok函数,则会出现问题。此时应该使用升级版本的strtok_s或者strtok_r。
2、strtok会破坏被分割的字符串的完整性,相应的解释详见引用1。
如果同时需要对多余一个字符串进行分割,使用本文第二个标题下的第二个代码模板。
引用:
1、csdn hustfoxy的专栏 strtok、strtok_s、strtok_r 字符串分割函数
2、百度知道
3、ChinaUnix 坚持到底 标准C中字符串分割方法
本文介绍使用函数strtok及其衍生函数来对字符串进行切分。
strtok函数的常规使用方法——同时处理单一字符串
函数原型:char * strtok (char *str, const char * delimiters);传入参数:str 目标字符串,待分割的字符串
delimiters 分隔符字符串。由于是一个字符串,而不是一个字符,因此可以在一次分割过程中同时使用多个分隔符对str进行分割
返回值 :返回值是char*,并不是char**。因此仅仅使用一次该函数并不能得到分割后的结果。
使用模板如下所示:
char str[]="ab:cd,ef"; char *ptr; ptr = strtok(str, ",:"); while(ptr != NULL){ // 对ptr的使用,如输出 printf("ptr=%s\n",ptr); ptr = strtok(NULL, ",:"); }
运行结果为:
ptr=ab
ptr=cd
ptr=ef
对该模板的解释:
1、由于返回值是一个char*类型,故对strtok函数的一次调用只可以得到目标字符串str的一个分割后的子串。必须通过循环不断地得到其分割后的子串。
2、第3行和第7行是在写while循环中的固定模板,第3行是初始化循环变量,第7行是改变循环变量。在使用strtok函数中,第7行中第一个参数是NULL。
3、分隔符字符串包含两个字符,从运行结果中可以看出,在逗号和冒号处都进行了分割。
4、该函数支持空格分隔符。
strtok函数的进阶使用方法——同时处理多个字符串
现在以同时处理2个字符串为例来说明。按照上面的模板,我编写了同时处理2个字符串的代码片段,如下:char str[]="1.0"; char str1[]="11.22.33"; char *ptr; char *ptr1; ptr = strtok(str, "."); ptr1 = strtok(str1, "."); while(ptr != NULL && ptr1 != NULL){ printf("ptr=%s\n",ptr); printf("ptr1=%s\n",ptr1); ptr = strtok(NULL, "."); ptr1 = strtok(NULL, "."); }运行结果如下:
ptr=1
ptr1=11
ptr=22
ptr1=33
对上述代码和结果的解释:
strtok函数在对待分割的字符串进行分割时,将分割后的中间结果保存在一个静态变量中,该静态变量对于用户来说是隐藏的,是该函数自动创建的辅助变量。假设该变量名为temp。运行至第6行时,temp中的值为第一次分割完str之后的结果“0”。运行至第7行时,temp中的值为第一次分割完str1之后的结果“22.33”。进入while循环之后,第一次运行第13行时,由于temp中的值是“22.33”,因此分割完之后得到的结果为“22”。接着运行第14行,得到“33”。
这种现象是由于函数strtok使用了没有加锁的静态变量,当多个线程同时访问这个变量时,结果就会不可控。最简单的解决方案就是为不同的进程开辟不同的变量,用来分别保存各自的中间结果。
在windows中,strtok_s函数实现了上述功能;在Linux中,相应的升级版函数为strtok_r。他们的函数原型分别为:
char *strtok_s( char *strToken, const char *strDelimit, char **buf);
char *strtok_r(char *str, const char *delim, char **saveptr);
第3个参数为代替静态变量的用于存储中间结果的变量。如下为使用strtok_r函数的模板:
char str[]="1.0"; char str1[]="11.22.33"; char *ptr; char *ptr1; char *saveptr; char *saveptr1; ptr = strtok_s(str, ".", &saveptr); ptr1 = strtok_s(str1, ".", &saveptr1); while(ptr != NULL && ptr1 != NULL){ printf("ptr=%s\n",ptr); printf("ptr1=%s\n",ptr1); ptr = strtok_s(NULL, ".", &saveptr); ptr1 = strtok_s(NULL, ".", &saveptr1); }运行结果如下:
ptr=1
ptr1=11
ptr=0
ptr1=22
总结:
strtok的好处:strtok是按照字符对字符串进行分割,可以同时处理多个字符strtok的缺点:
1、strtok会将还没有进行分割的字符串存储在中间辅助变量中,如果同时使用多个strtok函数,则会出现问题。此时应该使用升级版本的strtok_s或者strtok_r。
2、strtok会破坏被分割的字符串的完整性,相应的解释详见引用1。
如何使用该函数:
如果同时只对一个字符串进行分割,使用本文第一个标题下的代码模板。如果同时需要对多余一个字符串进行分割,使用本文第二个标题下的第二个代码模板。
使用strtok制作split函数:
详见引用2。使用strstr函数
详见引用3。但是我在vs2010中报内存错误,不明白为什么。引用:
1、csdn hustfoxy的专栏 strtok、strtok_s、strtok_r 字符串分割函数
2、百度知道
3、ChinaUnix 坚持到底 标准C中字符串分割方法
相关文章推荐
- C++杂记
- [杂记]C/C++ ·书籍·And More
- C++杂记 2011/12/12
- C、C++易错知识点杂记(2)
- C++基础杂记
- C、C++易错知识点杂记(3)
- C++杂记 2011/12/13
- c++ 杂记
- C、C++易错知识点杂记(1)
- c++学习杂记(1)
- VS2005 C++ 手机开发杂记(上)
- C++杂记 05/08/2011 开始一个完整的WTL例子
- C++ Primer_顺序容器杂记
- VS2005 C++ 手机开发杂记(下)
- c++学习杂记(2)
- c++学习杂记(4)
- C++杂记
- C++杂记 2011/12/15
- 个人C++学习杂记
- 杂记之C语言之const常量在C++中的表现