=Start=
正文:
参考解答:
函数原型:
char *strtok(char *s, const char *delim);
char *strsep(char **s, const char *delim);
功能:strtok和strsep两个函数的功能都是用来分解字符串为一组字符串。s为要分解的字符串,delim为分隔符字符串。
返回值:从s开头开始的一个个子串,当没有分割的子串时返回NULL。
相同点:两者都会改变源字符串,想要避免,可以使用strdupa(由allocate函数实现)或strdup(由malloc函数实现)。
不同点:strtok函数第一次调用时会把s字符串中所有在delim中出现的字符替换为NULL。然后通过依次调用strtok(NULL, delim)得到各部分子串。strsep函数将返回delim分隔符前面的字符串,s将指向分隔符之后的字符串
测试代码:
#include <stdio.h>
#include <string.h>
int main(void) {
char s[] = "hello, world! welcome to china!";
char delim[] = " ,!";
printf("Original: '%s'\n\n", s);
char *token;
for(token = strtok(s, delim); token != NULL; token = strtok(NULL, delim)) {
printf(token);
printf("+");
}
printf("\n");
printf("After strsep: '%s'\n", s);
return 0;
}
/*输出结果为:
Original: 'hello, world! welcome to china!'
hello+world+welcome+china+
After strsep: '%s'
*/
&
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char str[] = "acdeabx";
char *p = NULL;
char delim[] = "ab"; /* delim是分隔符的集合 */
printf("the original str is : %s\n\n", str);
int in = 0;
p = strtok(str, delim);
while(p != NULL){
printf("the character is :%s\n", p);
printf("the str is : %s\n", str); /* 源字符串str发生了变化 */
p = strtok(NULL, delim);
}
}
&
#include <stdio.h>
#include <string.h>
int main(){
char str[] = "2,张三,89,99,66";
// char str[] = ",,2,张三,89,99,66";
// str是一个指针常量,而strsep的第一个参数需要一个指向指针的指针,所以不能对str做取地址操作,这里再定义一个指针变量就可以取地址操作了。否则会出现段错误。
char *strv = str;
char *token = strsep(&strv, ",");
while(token != NULL){
printf("%s\t", token);
token = strsep(&strv, ",");
}
printf("\n");
return 0;
}
&
#include <stdio.h>
#include <string.h>
int main(void) {
char source[] = "hello, world! welcome to china!";
char delim[] = " ,!";
printf("Original: '%s'\n\n", source);
char *s = strdup(source);
char *token;
for(token = strsep(&s, delim); token != NULL; token = strsep(&s, delim)) {
printf(token);
printf("+");
}
printf("\n\n");
printf("After strsep: '%s'\n", s);
return 0;
}
/*输出结果为:
Original: 'hello, world! welcome to china!'
hello++world++welcome+to+china++
After strsep: '%s'
*/
&
为什么用strtok时子串中间只有一个”+”,而strsep却有多个”+”呢?文档中有如下的解释:
One difference between strsep and strtok_r is that if the input string contains more than one character from delimiter in a row strsep returns an empty string for each pair of characters from delimiter. This means that a program normally should test for strsep returning an empty string before processing it.
大意是:如果输入的字符串有连续的多个字符属于delim,(此例source中的逗号+空格,感叹号+空格等就是这种情况),strtok会返回NULL,而strsep会返回空串””。因而我们如果想用strsep函数分割字符串必须进行返回值是否是空串的判断。这也就解释了strsep的例子中有多个”+”的原因。
我们在自己的程序中最好尽量避免使用strtok,转而使用strsep。因为:
* – Added strsep() which will replace strtok() soon (because strsep() is reentrant and should be faster). Use only strsep() in new code, please.
即,strsep()相比strtok()来说,它是可重入(reentrant)的(更安全),且速度更快。
参考链接:
- 关于Linux C中函数strtok使用要点
- Linux C函数strtok解析
- 关于函数strtok和strtok_r的使用要点和实现原理(一)
- C中strtok()函数和strtok_r()函数
- strtok和strsep函数详解
- Linux系统库函数之strsep
=END=
《 “C语言的 strtok 和 strsep 函数的使用” 》 有 3 条评论
在Linux下用C实现根据指定分隔符对字符串进行切分
https://stackoverflow.com/questions/9210528/split-string-with-delimiters-in-c
https://stackoverflow.com/questions/2523467/how-to-split-a-string-to-2-strings-in-c
https://stackoverflow.com/questions/15472299/split-string-into-tokens-and-save-them-in-an-array #需要提前申请固定大小的array
https://stackoverflow.com/questions/4513316/split-string-in-c-every-white-space
https://stackoverflow.com/questions/11198604/c-split-string-into-an-array-of-strings
strtok和strsep的不同之处
https://stackoverflow.com/questions/7218625/what-are-the-differences-between-strtok-and-strsep-in-c/
strsep和strtok_r替代strtok
http://www.cnblogs.com/zhaoyl/p/5774134.html
深究strtok系列函数
http://answerywj.com/2019/05/21/man-strtok/
`
1. 函数说明
1.1. 说明
1.2. 参数
1.3. 返回值
2. 示例
3. 使用注意事项
3.1. 不会生成新的字符串,只是在源字符串上做了修改,源字符串会发生变化
3.2. 第一个参数不可为字符串常量
3.3. 若在第一次提取子串后,继续对源字符串进行提取,应在其后的调用中将第一个参数置为空值NULL
3.4. 第二个参数是分割符的集合,支持多个分割符
3.5. 若首字符为分割符,则会被忽略
3.6. strtok为不可重入函数,使用strtok_r更灵活和安全
4. 源码
5. Reference
`