C语言中strtok和strsep的区别
char *strtok ( char * str, const char * delimiters );
char *strsep(char **stringp, const char *delim);
strtok和strsep均可用于str字符串的分割。
相同部分:
对该函数的调用序列将str拆分为token,这些token是由作为定界符一部分的任何字符分隔的连续字符的序列。
首次调用时,该函数需要一个C字符串作为str的参数,该字符串的第一个字符用作扫描令牌的起始位置。在随后的调用中,该函数需要一个空指针,并使用最后一个标记结束后的位置作为扫描的新起始位置。
为了确定token的开头和结尾,该函数首先从起始位置扫描未包含在定界符中的第一个字符(该字符成为token的开头)。然后从token的开头开始扫描定界符中包含的第一个字符,该字符成为token的末尾。如果找到终止的空字符,扫描也会停止。
token的此结尾将自动替换为空字符(NULL),并且token的开头由函数返回。
一旦在对strtok的调用中找到了str的终止null字符,此函数的所有后续调用(将null指针作为第一个参数)都将返回null指针。
找到下一个标记的点由在下一次调用时使用的函数在内部保留(不需要特殊的库实现来避免数据争用)。
因此,两者都会对原字符串进行修改。
不同部分:
1.strtok()和strsep()之间的主要区别在于strtok()是C标准的,因此也是通过POSIX);而strsep()不是标准化的(通过C或POSIX;它在GNU C中可用) 库,起源于BSD。
对于内核编程中,是没有strtok函数的,因此只能使用strtok。
2.strtok内部记录上次调用字符串的位置,所以是不可重入的,不支持多线的,其可重入版本为strtok_r。
strsep使用传入的参数来确定字符串的起始位置,是可重入的,也是Linux kernel推荐的函数,strtok的替代品。
3.当遇到多个连续的分隔符时,strtok会把这些多个连续的分割符当做一个来处理,而strsep会依次处理,会返回空字符串
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
41
42
43
44
45
46
|
#include <stdio.h> #include <string.h> #define STRING_FOR_TESTING "{0x1,0x2}, {{{{{{{{{{{{0x3,0x4}, {0x5,0x6},{0x7,0x8},{0x9,0x10},{0x11,0x12},{0x13,0x14}," int main() { char input[] = STRING_FOR_TESTING; char input_tok[] = STRING_FOR_TESTING; char input_sep[] = STRING_FOR_TESTING; char *token; char *pCur; printf ( "origin input: %s, size:%lu\n" , input, sizeof (input)); printf ( "************ strtok start ************\n" ); printf ( "input_tok=%p\n" , input_tok); token = strtok (input_tok, "{" ); while (token != NULL) { printf ( "strtok:%s -- token=%p\n" , token, token); token = strtok (NULL, "{" ); } printf ( "now input: %85s, size:%lu\n" , input_tok, sizeof (input_tok)); printf ( "************ strtok end ************\n" ); printf ( "************ strsep start ************\n" ); pCur = input_sep; printf ( "input_sep=%p\n" , input_sep); token = strsep(&pCur, "{" ); while (token != NULL) { printf ( "strsep:%s-- token=%p pCur=%p\n" , token, token, pCur); token = strsep(&pCur, "{" ); } printf ( "now input: %85s, size:%lu\n" , input_sep, sizeof (input_sep)); printf ( "************ strsep end ************\n" ); return 0; } |
执行结果:
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
|
origin input: {0x1,0x2}, {{{{{{{{{{{{0x3,0x4}, {0x5,0x6},{0x7,0x8},{0x9,0x10},{0x11,0x12},{0x13,0x14},, size:89 ************ strtok start ************ input_tok=0x7fffda95d200 strtok :0x1,0x2}, -- token=0x7fffda95d201 strtok :0x3,0x4}, -- token=0x7fffda95d217 strtok :0x5,0x6}, -- token=0x7fffda95d222 strtok :0x7,0x8}, -- token=0x7fffda95d22c strtok :0x9,0x10}, -- token=0x7fffda95d236 strtok :0x11,0x12}, -- token=0x7fffda95d241 strtok :0x13,0x14}, -- token=0x7fffda95d24d now input: {0x1,0x2}, , size:89 ************ strtok end ************ ************ strsep start ************ input_sep=0x7fffda95d260 strsep:-- token=0x7fffda95d260 pCur=0x7fffda95d261 strsep:0x1,0x2}, -- token=0x7fffda95d261 pCur=0x7fffda95d26c strsep:-- token=0x7fffda95d26c pCur=0x7fffda95d26d strsep:-- token=0x7fffda95d26d pCur=0x7fffda95d26e strsep:-- token=0x7fffda95d26e pCur=0x7fffda95d26f strsep:-- token=0x7fffda95d26f pCur=0x7fffda95d270 strsep:-- token=0x7fffda95d270 pCur=0x7fffda95d271 strsep:-- token=0x7fffda95d271 pCur=0x7fffda95d272 strsep:-- token=0x7fffda95d272 pCur=0x7fffda95d273 strsep:-- token=0x7fffda95d273 pCur=0x7fffda95d274 strsep:-- token=0x7fffda95d274 pCur=0x7fffda95d275 strsep:-- token=0x7fffda95d275 pCur=0x7fffda95d276 strsep:-- token=0x7fffda95d276 pCur=0x7fffda95d277 strsep:0x3,0x4}, -- token=0x7fffda95d277 pCur=0x7fffda95d282 strsep:0x5,0x6},-- token=0x7fffda95d282 pCur=0x7fffda95d28c strsep:0x7,0x8},-- token=0x7fffda95d28c pCur=0x7fffda95d296 strsep:0x9,0x10},-- token=0x7fffda95d296 pCur=0x7fffda95d2a1 strsep:0x11,0x12},-- token=0x7fffda95d2a1 pCur=0x7fffda95d2ad strsep:0x13,0x14},-- token=0x7fffda95d2ad pCur=(nil) now input: , size:89 ************ strsep end ************ |