[C++杂记] string串切分

来源:互联网 发布:sqlserver 附加数据库 编辑:程序博客网 时间:2024/05/23 01:59

在做LeetCode上面的Compare Version Number时,需要对所需要的串进行分割操作。对字符串的切分操作也是很常规的一种操作。

本文介绍使用函数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中字符串分割方法


0 0
原创粉丝点击