一、函数strtok_r的作用
函数strtok_r可以将一个字符串按照指定的分割符进行分割,例如将字符串:"hello, jason, please come here",按照","分割为:
"hello"
"jason"
"please come here"
也可以按照分隔符" "分割为:
"hello,"
"jason,"
"please"
"come"
"here"
二、函数strtok_r说明及其注意事项
函数strtok_r是函数strtok的可重入版本,也即线程安全版本。在函数strtok中剩余字符串是存储在一个静态变量中,因此,多线程在使用该静态变量时引起冲突;而strtok_r则使用用户传入的指针为每个用户saveptr重新申请变量,因而可以保证线程安全。其定义形式为:
#include <string.h>
char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);
其中:
char *str是被分割字符串,如上面例子中的"hello, jason, please come here",第一次调用函数strtok_r时此指针一定不能为空,连续分割同一个字符串时,第一调用之后的调用需将str设置为NULL。
const char *delim是分隔符,也是个字符串指针,例如上面例子中的","或者" "。
char **saveptr是一个供内部使用的指针,用于保存上次分割剩下的字串。
返回值是个指针,用于返回从被分割字符串中得到的第一个目标子串。
注意:虽然函数strtok_r可以将一个字符串进行分割,但是每次分割只能得到第一个被分割的字串,例如:按照" "分割"hello, jason, please come here"时,
第一次调用strtok_r,参数str所指向的内存中存放被分割字符串"hello, jason, please come here",参数delim为分隔符串" "的指针,saveptr指向一个空指针变量,得到"hello,";同时saveptr中就保存了剩下的子串"jason, please come here";
第二次调用strtok_r,参数str设置为空,参数delim和saveptr不变,得到"jason,",同时saveptr中保存了剩下的子串"please come here";
第三次调用strtok_r(同第二次)得到"please come here";
三、示例代码
下面是一个测试函数,主要测试strtok_r函数的用法。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char pSrc[] = "this/is/jason;/i/am/from/xi'an/china";
char* pToken = NULL;
char* pSave = NULL;
char* pDelimiter = "/";
pToken = strtok_r(pSrc, pDelimiter, &pSave);
printf("Begin:\n");
while(pToken){
printf(" pToken[%s]; pSave[%s]\n",pToken,pSave);
pToken = strtok_r(NULL, pDelimiter, &pSave);
}
printf("End!\n");
return 0;
}
其输出结果为:
Begin:
pToken[this]; pSave[is/jason;/i/am/from/xi'an/china]
pToken[is]; pSave[jason;/i/am/from/xi'an/china]
pToken[jason;]; pSave[i/am/from/xi'an/china]
pToken[i]; pSave[am/from/xi'an/china]
pToken[am]; pSave[from/xi'an/china]
pToken[from]; pSave[xi'an/china]
pToken[xi'an]; pSave[china]
pToken[china]; pSave[]
End!