北大青鸟佳音旗舰

c函数 strtok和strtok_r详解

点击数: 更新时间:2010-06-04 14:23:38
 

函数名:   strtok

  功     能:   查找由在第二个串中指定的分界符分隔开的单词

  用     法:   char   *strtok(char   *str1,   char   *str2);

  程序例:

  #include   <string.h>

  #include   <stdio.h>

  int   main(void)

  {

  char   input[16]   =   "abc,d";

  char   *p;

  /*   strtok   places   a   NULL   terminator

  in   front   of   the   token,   if   found   */

  p   =   strtok(input,   ",");

  if   (p)       printf("%s\n",   p);

  /*   A   second   call   to   strtok   using   a   NULL

  as   the   first   parameter   returns   a   pointer

  to   the   character   following   the   token     */

  p   =   strtok(NULL,   ",");

  if   (p)       printf("%s\n",   p);

  return   0;

  }

  带有_r的函数主要来自于UNIX下面。所有的带有_r和不带_r的函数的区别的是:带_r的函数是线程安全的,r的意思是reentrant,可重入的。

  上述程序运行的结果是

  abc

  d

  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<stdio.h>

  #include<string.h>

  #define INFO_MAX_SZ 255

  int main()

  {

  int in=0;

  char buffer[INFO_MAX_SZ]="Fred male 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 %d strings\n",i);

  for (int j=0; j<in; j++)

  printf(">%s<\n",p[j]);

  return 0;

  }

这个程序输出为:

  Here we have 4 strings

  >Fred<

  >male<

  >25<

  >***<

  这只是一小段的数据,并不是我们需要的。但这是为什么呢? 这是因为strtok使用一个static(静态)指针来操作数据,让我来分析一下以上代码的运行过程:

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

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

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

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

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

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

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

  3. 使用strtok_r

  在这种情况我们应该使用strtok_r, strtok reentrant.

  char *strtok_r(char *s, const char *delim, char **ptrptr);

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

  代码:

  QUOTE:

  #include<stdio.h>

  #include<string.h>

  #define INFO_MAX_SZ 255

  int main()

  {

  int in=0;

  char buffer[INFO_MAX_SZ]="Fred male 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 %d strings\n",i);

  for (int j=0; jn<i; j++)

  printf(">%s<\n",p[j]);

  return 0;

  }

  这一次的输出为:

  Here we have 12 strings

  >Fred<

  >male<

  >25<

  >***<

  >John<

  >male<

  >62<

  >***<

  >Anna<

  >female<

  >16<

  >***<

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

  红色为strtok_r的outer_ptr指向的位置,

  紫色为strtok_r的inner_ptr指向的位置,

  蓝色为strtok对字符串的修改

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

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

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

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

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

  6   "Fred\0male\025\0John male 62\0Anna female 16"//进入内循环

 


            

相关信息
没有相关内容
©Copyright2004 - 2009 www.bjaccp.com, All Rights Reserved
版权所有2004-2008 北大青鸟APTECH( 北京佳音旗舰 ) 授权培训中心
地址:北京西城区北礼士路100号( 阜成门华联商厦西门北侧北走50米)100037北大青鸟地址
京ICP备06064589号
51.la