码迷,mamicode.com
首页 > 其他好文 > 详细

字符串分割

时间:2015-02-28 13:13:01      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:

1.利用sscaf处理固定长度与分隔符的字符串

#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]);

%[^,] 表示匹配到【,】符号之前的所有字符串

2.利用标准库函数strtok处理长度与分隔符变化的字符串

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

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!