您的位置:首页 > 编程语言 > C语言/C++

c++分割字符串,strtok与strtok_r的使用记录

2017-07-26 22:01 555 查看

strtok的使用

写在最开头,strtok是线程不安全的,在使用时一定要考虑到这点。strtok函数使用一个静态变量存储中间值,不要在多线程编程下使用这个函数,不然一定出错。

这个函数头文件是 string.h,定义为:

char * strtok(char *s, const char *delim)


char* s为源字符串,即要被切分的字符串,char * delim为分隔符集合,意味着可以放入多个分隔符,都可以生效,比如可以这样 :

strtok(s,"\t");
strtok(s,"\t\r");
strtok(s,"\n\t");


该函数返回值即为切割完获得的第一个字符串,比如以空格分隔的字符串s,其指向字符串为“hi guys”,第一次执行后获得的返回值是”hi”。

以下是一个样例,执行完第一次后,后面的执行第一个参数可以为NULL,因为对应的字段已经存储在一个静态变量中了,下次可以直接调用。

/* strtok example */
#include <stdio.h>
#include <string.h>

int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}


以上,是用例,当然也有线程安全的strtok可用,但是这个的函数的效率相当底下,不建议使用,看定义可以看出其结构和strtok类似,只是多了一个saveptr参数,这个参数是用来记录被分割字符串的,即使用者需要自己声明一个char ** saveptr传入其中,saveptr记录的是每次被分割后剩余的部分。比如”it is a nice day“,以空格分隔,执行完一次后saveptr上存储的是”is a nice day”。

定义如下:

char *strtok_r(char *str, const char *delim, char **saveptr);


用法与strtok类似,附上用例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int
main(int argc, char *argv[])
{
char *str1, *str2, *token, *subtoken;
char *saveptr1, *saveptr2;
int j;

if (argc != 4) {
fprintf(stderr, "Usage: %s string delim subdelim\n",
argv[0]);
exit(EXIT_FAILURE);
}

for (j = 1, str1 = argv[1]; ; j++, str1 = NULL) {
token = strtok_r(str1, argv[2], &saveptr1);
if (token == NULL)
break;
printf("%d: %s\n", j, token);

for (str2 = token; ; str2 = NULL) {
subtoken = strtok_r(str2, argv[3], &saveptr2);
if (subtoken == NULL)
break;
printf(" --> %s\n", subtoken);
}
}

exit(EXIT_SUCCESS);
}


最后,个人认为,这两个函数有着不小的缺陷,谨慎使用。

参考:

http://www.cplusplus.com/reference/cstring/strtok/

https://linux.die.net/man/3/strtok_r
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数 分割 c语言