strtok()原型:
char * strtok(char *s, const char *delim);
函数说明:strtok()用来将字符串分割成一个个片段。参数s 指向欲分割的字符串,参数delim 则为分割字符串,当strtok()在参数s 的字符串中发现到参数delim 的分割字符时则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s 字符串,往后的调用则将参数s 设置成NULL。每次调用成功则返回下一个分割后的字符串指针。
返回值:返回下一个分割后的字符串指针,如果已无从分割则返回NULL。
问题:
1、“改为\0 字符”:strtok()会修改源字符串,所以使用时最好重新拷贝一份。
2、“在第一次调用时,strtok()必需给予参数s 字符串,往后的调用则将参数s 设置成NULL”:往后的调用则将参数s 设置成NULL是因为第一次调用时将切割后的字符串存在了函数的静态变量中,传入NULL表示使用静态变量中的数据。所以若程序调用栈中有两个及以上函数或多线程同时调用strtok()会出现问题。
多函数调用举例:
func1(..)
{
...
tmp = strtok(str, delim);
while(strtok(NULL, delim))
{
...
}
...
}
func()
{
...
tmp = strtok(str, delim);
while(strtok(NULL, delim))
{
...
func1();
...
}
...
}
由于func1()中改变了strtok()中静态变量值导致func()出错;
解决办法:使用strtok_r()
函数原型为 char *strtok_r(char *str, const char *delim, char **saveptr);
strtok_r实际上就是将strtok内部隐式保存的this指针,以参数的形式与函数外部进行交互。由调用者进行传递、保存甚至是修改。需要调用者在连续切分相同源字符串时,除了将str参数赋值为NULL,还要传递上次切分时保存下的saveptr。