strtoc函数原码剖析

来源:互联网 发布:非凡软件站手机版 编辑:程序博客网 时间:2024/05/17 23:29

strtoc函数原码剖析


先用自己的语言描述一下函数运作的过程(相信这是了解此函数最好的方法):
原型:char *strtok(char *s, char *delim);


功能:分解字符串为一组标记串。s为要分解的字符串,delim为分隔符字符串。


说明:首次调用时,s必须指向要分解的字符串,随后调用要把s设成NULL。 strtok在s中查找包含在delim中的字符并用NULL('\0')来替换,直到找遍整个字符串。 返回指向下一个标记串。当没有标记串时则返回空字符NULL。


****具体流程:
1.第一次传入字符串指针,分隔符指针,在字符串中寻找此分隔符,没有返回NULL;
如果有,首先置此分隔符位为‘\0’,之后返回字符串开始地址;
并在此保存一指向分隔符下一个字符的指针(这一点非常重要,全局变量保存);
2.第二次传入参数为NULL和分隔符指针,便将保存的指向上次找到分隔符的下一个字符指针拿出来,从此开始找下一个分隔符;
其余操作和第一次相同;
3.如果直到找到字符串结束任然没找到分隔符,就返回此次定义的字符串首地址(第一次是整个字符串首地址,以后是上次找到分隔符后的下一个字符指针);
****


  char*  strtok_r(char* string_org,const char* demial);就如函数定义传入一字符串指针和分隔字符;

/*
   1: char*  strtok_r(char* string_org,const char* demial)
   2: {
   3: static unsigned char* last; //保存分隔后剩余的部分
   4: unsigned char* str;         //返回的字符串
   5: const unsigned char* ctrl = (const unsigned char*)demial;//分隔字符
   6:  
   7: //把分隔字符放到一个索引表中。定义32是因为ASCII字符表最多是0~255个,也是说用最大的255右移3位,也就是除以8一定会是32中的一个数。
   8: unsigned char map[32]; 
   9: int count;
  10:  
  11: //把map全部清为0,之后相与的操作,与0的都为0
  12: for (count =0; count <32; count++)
  13:     {
  14:     map[count] = 0;
  15:     }
  16:  
  17: //把匹配字符放入表中
  18: //放入的算法是把匹配字符右移3位,相当于除以8,的数值 并上(加上)
  19: //匹配字符与7,得到低3位,得出的结果,是把1左移的位数。最大左移位数是7,也就是所表示的最大值是128,    
  20: do 
  21:     {
  22:     map[*ctrl >> 3] |= (1 << (*ctrl & 7));
  23:     } while (*ctrl++);
  24:     
  25: //原始字符串是否为空,如果为空表示第二次获取剩余字符的分隔部分。    
  26: if (string_org)
  27:     {
  28:     str = (unsigned char*)string_org;
  29:     } 
  30: else
  31:     {
  32:     str = last;
  33:     }
  34:  
  35: //在表中查找是否有匹配的字符,如果有略过    
  36: while ((map[*str >> 3] & (1 << (*str & 7)))  && *str)
  37:     {
  38:     str++;
  39:     }
  40:  
  41: //重置需要扫描的字符串    
  42: string_org = (char*)str;
  43:  
  44: //开始扫描
  45: for (;*str; str++)
  46:     {
  47:     if ( map[*str >> 3] & (1 << (*str & 7)))
  48:         {
  49:         *str++ = '\0';//当找到时,把匹配字符填为0,并且把str指向下一位。
  50:         break; //退出循环             
  51:         }
  52:             
  53:     }
  54:     
  55: last =str; // 把剩余字符串的指针保存到静态变量last中。
  56:     
  57: if (string_org == (char*)str)
  58:     {
  59:     return NULL; //没有找到,也就是没有移动指针的位置,返回NULL
  60:     }
  61: else
  62:     {
  63:     return string_org; //找到了,返回之前字符串的头指针
  64:     }
  65: }
  */