标签:
#define RAW_STRING "aaa,bbb,ccc,ddd"
char szBuf[4][8]= {0}; int ret = 0;
ret = sscanf(RAW_STRING,"%[^,],%[^,],%[^,],%[^,]",&szBuf[0],&szBuf[1],&szBuf[2],&szBuf[3]);
%[^,] 表示匹配到【,】符号之前的所有字符串
strtok为不可重用函数线程不安全的标准库函数
原型:extern char *strtok(char *s, char *delim);
功能:分解字符串为一组标记串。s为要分解的字符串,delim为分隔符字符串。
说明:首次调用时,s必须指向要分解的字符串,随后调用要把s设成NULL。
strtok在s中查找包含在delim中的字符并用NULL(‘\0‘)来替换,直到找遍整个字符串。
返回指向下一个标记串。当没有标记串时则返回空字符NULL。
#define RAW_STRING "aaa,bbb,ccc,ddd" char s[64] = {0}; char *token = ","; char *s_ptr = NULL; strcpy(s,RAW_STRING); s_ptr = strtok(s,token); while(s_ptr) { printf("[%s]\n",s_ptr); s_ptr = strtok(NULL,token); }
首次使用src为分割的字符串(绝对不可以是字符串常量,否则修改函数内部修改程序只读代码段会段错误)
若返回非空则代表查找token成功返回首个字符串分段
之后src传NULL值,每次调用此函数会分别返回剩下的字符串分段,当全部分段完成查找并后返回NULL
通过每次执行会发现此函数每一次调用进行的操作是
1.查找token
2.将首次出现的token的位置修改为‘\0‘
3.返回查找的原字符串
此函数内部有一个静态变量保存着每次操作后token位置后的首个字符串起始位置的指针,从而在后面的调用中能以此为基础分割剩余的字符串
由此可见此函数是线程不安全的不可重入函数
当多个线程同时调用时,其函数内部的静态指针变量的值不可确定
windows(VS2008)以上平台有一个安全的函数:
char * __cdecl strtok_s( _Inout_opt_z_ char * _Str, _In_z_ const char * _Delim, _Inout_ _Deref_prepost_opt_z_ char ** _Context );
_Str为原字符串
_Delim为分隔符
_Context为外部传入的二级指针变量用于修改每次操作后token位置后的首个字符串起始位置的指针
将原标准库函数内部的静态指针变量取消从而实现线程可重入
#define RAW_STRING "aaa,bbb,ccc,ddd"
char s[64] = {0}; char *token = ","; char *s_next= NULL,*s_ptr= NULL; strcpy(s,RAW_STRING); s_ptr = strtok_s(s,token,&s_next); while(s_ptr) { printf("[%s]\n",s_ptr); s_ptr = strtok_s(NULL,token,&s_next); }
GUN GCC下也有一个strtok函数的可重入版本用法同strtok_s
为char *strtok_r(char *str, const char *delim, char **saveptr);
str为要分解的字符串,delim为分隔符字符串。char **saveptr参数是一个指向char *的指针变量,用来在strtok_r内部保存切分时的上下文,以应对连续调用分解相同源字符串。
char* mystrtok_s(char* src,const char* token,char** next) { char *pToken = NULL,*pBegin = NULL;
if( !*next ) { return NULL; }
pBegin = src ? src : *next;
pToken = strstr(pBegin,token); if( pToken ) { *pToken = ‘\0‘; *next = pToken + 1; } else { *next = NULL; }
return pBegin; }
标签:
原文地址:http://my.oschina.net/mlgb/blog/380660