C标准库函数strtok使用心得
C标准库函数strtok使用心得
strtok函数
大家都知道strtok函数可以用来对字符串进行分割,大大满足了我们处理字符串时候的需求,不需要我们自己再去写一些分割函数。
自己在使用过程中也总结了两点需要注意的地方跟大家分享一下:
首先这个函数的原型
char *strtok(char s[], const char *delim);
strtok()用来将字符串分割成一个个片段。
参数s指向欲分割的字符串,参数delim则为分割字符串中包含的所有字符。
当strtok()在参数s的字符串中发现参数delim中包含的分割字符时,则会将该字符改为\0 字符。
在第一次调用时,strtok()必需给予参数s字符串,往后的调用则将参数s设置成NULL。
每次调用成功则返回指向被分割出片段的指针。
一般使用的代码是:
1 | char* temp1; |
当然如果有多个s中有多个delim分隔符的时候,可以用while循环来逐个分割,要注意的是strtok的第一个参数,除了第一次采用s后,之后全部采用NULL。
现在回归正题,从两个参数分别说一下strtok需要注意的地方是:
1. 第一个参数char s[]
这个参数需要注意的是,s字符串所在的地址指向的值必须是可修改的,因为strtok函数内部实现中会去先找到delim的位置,然后将delim位置指向的字符修改为’\0’,然后逐个取出。
所以如果s地址位于常量区、或者堆区,使用这个函数的时候会发生错误。
如下:
1 | char* s = "aa,bb,cc"; |
由于”aa,bb,cc”是位于堆区的,所以指向’,’的指针*p,不能再被*p = ‘\0’。
2. 第二个参数delim
delim分隔符在使用的时候,要注意的是都想当然的以为函数在分割字符串时完整匹配分隔符delim。
比如delim=”ab”,则对于”acdeab”这个字符串,函数提取出的是”acde”。
至少我在第一次使用的时候也是这么认为的。
其实我们都错了,我是在看函数的源代码时才发现这个问题的。
且看下面的例子
1 | int main(void) |
输出的结果为:
the character is :cde
第一次调用之后的结果竟然是”cde”,而非我们所想的结果。这是为什么呢?
我们回到GNU C Library中对strtok的功能定义:
“Parse S into tokens separated by characters in DELIM”。
也就是说包含在delim中的字符均可以作为分隔符,而非严格匹配。
可以把delim理解为分隔符的集合。这一点是非常重要的。
当然,我们在分解字符串的时候,很少使用多个分隔符。这也导致,很多人在写例子的时候只讨论了一个分隔符的情况。有更多的人在看例子的时候也就错误的认识了delim的作用。
所以大家使用过程中要多注意了。




