C字符串分割

来源:互联网 发布:f22和歼20数据对比 编辑:程序博客网 时间:2024/05/22 03:43
1. strtok介绍
众所周知,strtok可以根据用户所提供的分割符(同时分隔符也可以为复数比如“,。”)
将一段字符串分割直到遇到"\0".

比如,分隔符=“,” 字符串=“Fred,John,Ann”
通过strtok 就可以把3个字符串“Fred”    “John”     “Ann”提取出来。
上面的C代码为

QUOTE:
int in=0;
char buffer[]="Fred,John,Ann"
char *p[3];
char *buff = buffer;
while((p[in]=strtok(buf,","))!=NULL) {
                i++;
                buf=NULL; }
如上代码,第一次执行strtok需要以目标字符串的地址为第一参数(buf=buffer),之后strtok需要以NULL为第一参数(buf=NULL)。指针列p[],则储存了分割后的结果,p[0]="John",p[1]="John",p[2]="Ann",而buf就变成   Fred\0John\0Ann\0。

2. strtok的弱点
让我们更改一下我们的计划:我们有一段字符串 "Fred male 25,John male 62,Anna female 16"我们希望把这个字符串整理输入到一个struct,

QUOTE:
struct person{ 
    char [25] name ; 
    char [6] sex;
    char [4] age;
}
要做到这个,其中一个方法就是先提取一段被“,”分割的字符串,然后再将其以“”(空格)分割。
比如: 截取 "Fred male 25" 然后分割成 "Fred" "male" "25"
以下我写了个小程序去表现这个过程:

QUOTE:
#include
#include
#define INFO_MAX_SZ 255
int main()
{
   int in=0;
   char buffer[INFO_MAX_SZ]="Fredmale 25,John male 62,Anna female 16";
   char *p[20];
   char *buf=buffer;

  while((p[in]=strtok(buf,","))!=NULL) {
            buf=p[in];
            while((p[in]=strtok(buf," "))!=NULL) {
                      in++;
                      buf=NULL;
                   }
                p[in++]="***"; //表现分割
                buf=NULL; }

   printf("Here we have %dstrings\n",i);
   for (int j=0; j
        printf(">%s<\n",p[j]);
   return 0;
}
这个程序输出为:
Here we have 4 strings
>Fred<</span>
>male<</span>
>25<</span>
>***<</span>
这只是一小段的数据,并不是我们需要的。但这是为什么呢?这是因为strtok使用一个static(静态)指针来操作数据,让我来分析一下以上代码的运行过程:

红色为strtok的内置指针指向的位置蓝色为strtok对字符串的修改

1. "Fredmale 25,John male 62,Anna female 16" //外循环

2. "Fred male 25\0Johnmale 62,Anna female 16" //进入内循环

3.   "Fred\0male25\0John male 62,Anna female 16"

4.   "Fred\0male\025\0Johnmale 62,Anna female 16"

5 "Fred\0male\025\0Johnmale 62,Anna female 16" //内循环遇到"\0"回到外循环

 "Fred\0male\025\0Johnmale 62,Anna female 16" //外循环遇到"\0"运行结束。

3. 使用strtok_r
在这种情况我们应该使用strtok_r, strtokreentrant. 
char *strtok_r(char *s, const char *delim, char**ptrptr);

相对strtok我们需要为strtok提供一个指针来操作,而不是像strtok使用配套的指针。
代码:

QUOTE:
#include
#include
#define INFO_MAX_SZ 255
int main()
{
   int in=0;
   char buffer[INFO_MAX_SZ]="Fredmale 25,John male 62,Anna female 16";
   char *p[20];
   char *buf=buffer;

   char*outer_ptr=NULL;
   char*inner_ptr=NULL;

  while((p[in]=strtok_r(buf,",",&outer_ptr))!=NULL){
            buf=p[in];
            while((p[in]=strtok_r(buf," ",&inner_ptr))!=NULL){
                      in++;
                      buf=NULL;
                   }
                p[in++]="***";
                buf=NULL; }

   printf("Here we have %dstrings\n",i);
   for (int j=0; jn
        printf(">%s<\n",p[j]);
   return 0;
}
这一次的输出为:
Here we have 12 strings
>Fred<</span>
>male<</span>
>25<</span>
>***<</span>
>John<</span>
>male<</span>
>62<</span>
>***<</span>
>Anna<</span>
>female<</span>
>16<</span>
>***<</span>


让我来分析一下以上代码的运行过程:

红色为strtok_r的outer_ptr指向的位置
紫色为strtok_r的inner_ptr指向的位置
蓝色为strtok对字符串的修改

1. "Fredmale 25,John male 62,Anna female 16" //外循环

2. "Fredmale 25\0Johnmale 62,Anna female 16"//进入内循环

3.   "Fred\0male25\0Johnmale 62,Anna female 16"

 "Fred\0male\025\0Johnmale 62,Anna female 16"

5 "Fred\0male\025\0Johnmale 62,Anna female 16" //内循环遇到"\0"回到外循环

 "Fred\0male\025\0Johnmale 62\0Annafemale16"//进入内循环
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怀孕了吐得厉害怎么办 玩网页游戏好卡怎么办 网页游戏占cpu高怎么办 微信有余额绑定其他名下怎么办 银行卡绑定支付余额不对怎么办 可乐机不制冷了怎么办 被淘宝卖家威胁怎么办 征信不好想贷款怎么办 急用钱征信不好怎么办 急用钱逾期不还怎么办 急用钱借款不还怎么办 做b超按压疼痛怎么办 做b超没有尿怎么办 b超憋不到尿怎么办 做b超前没有尿意怎么办 肝胆b超前喝水了怎么办 肝胆彩超喝水了怎么办 胆囊b超喝了水怎么办 系统b超照不到怎么办 思维彩超宝宝不动怎么办 怀孕七个月胎儿缺氧怎么办 怀孕29周小孩偏小怎么办 孕29周胎儿臀位怎么办 刚怀孕有囊肿该怎么办 食杏中毒怎么办吃什么 猫吃了扁桃仁怎么办 夏天来了??点狐臭怎么办? 我有一小点狐臭怎么办 淘客网站被微信屏蔽怎么办 微信老是屏蔽网站怎么办 华帝售后没人理怎么办 新开的网店没生意怎么办 淘小二介入买家举证不全怎么办 新股申购中签后钱不够怎么办 买的东西收不到怎么办? 拼多多按错收货怎么办 团购招生做到一半不如意怎么办 网购付款后卖家没有货怎么办 淘宝退货商家不同意退款怎么办 淘宝确认收货后卖家拒绝退款怎么办 淘宝卖家不同意退款怎么办