Bootstrap

strtok函数的实现

原型:extern char *strtok(char *s, char *delim);

 

  用法:#include <string.h>

 

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

 

  说明:首次调用时,s必须指向要分解的字符串,随后调用要把s设成NULL。

        strtok在s中查找包含在delim中的字符并用NULL('/0')来替换,直到找遍整个字符串。

        返回指向下一个标记串。当没有标记串时则返回空字符NULL。

 

  举例:

 

 

      // strtok.c

 

      #include <syslib.h>

      #include <string.h>

      #include <stdio.h>

 

      main()

      {

        char *s="Golden Global View";

        char *d=" ";

        char *p;

 

        clrscr();

 

        p=strtok(s,d);

        while(p)

        {

          printf("%s/n",s);

          strtok(NULL,d);

        }

 

        getchar();

        return 0;

      }

 

源码:

/***

*strtok.c - tokenize a string with given delimiters

*

*         Copyright (c) 1989-1997, Microsoft Corporation. All rights reserved.

*

*Purpose:

*         defines strtok() - breaks string into series of token

*         via repeated calls.

*

*******************************************************************************/

 

#include <cruntime.h>

#include <string.h>

#ifdef _MT

#include <mtdll.h>

#endif    /* _MT */

 

/***

*char *strtok(string, control) - tokenize string with delimiter in control

*

*Purpose:

*         strtok considers the string to consist of a sequence of zero or more

*         text tokens separated by spans of one or more control chars. the first

*         call, with string specified, returns a pointer to the first char of the

*         first token, and will write a null char into string immediately

*         following the returned token. subsequent calls with zero for the first

*         argument (string) will work thru the string until no tokens remain. the

*         control string may be different from call to call. when no tokens remain

*         in string a NULL pointer is returned. remember the control chars with a

*         bit map, one bit per ascii char. the null char is always a control char.

*

*Entry:

*         char *string - string to tokenize, or NULL to get next token

*         char *control - string of characters to use as delimiters

*

*Exit:

*         returns pointer to first token in string, or if string

*         was NULL, to next token

*         returns NULL when no more tokens remain.

*

*Uses:

*

*Exceptions:

*

*******************************************************************************/

 

char * __cdecl strtok (

          char * string,

          const char * control

          )

{

          unsigned char *str;

          const unsigned char *ctrl = control;

 

          unsigned char map[32];

          int count;

 

#ifdef _MT

          _ptiddata ptd = _getptd();

#else    /* _MT */

          static char *nextoken;

#endif    /* _MT */

 

          /* Clear control map */

          for (count = 0; count < 32; count++)

                  map[count] = 0;

 

          /* Set bits in delimiter table */

          do {

                  map[*ctrl >> 3] |= (1 << (*ctrl & 7));

          } while (*ctrl++);

 

          /* Initialize str. If string is NULL, set str to the saved

           * pointer (i.e., continue breaking tokens out of the string

           * from the last strtok call) */

          if (string)

                  str = string;

          else

#ifdef _MT

                  str = ptd->_token;

#else    /* _MT */

                  str = nextoken;

#endif    /* _MT */

 

          /* Find beginning of token (skip over leading delimiters). Note that

           * there is no token iff this loop sets str to point to the terminal

           * null (*str == '/0') */

          while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )

                  str++;

 

          string = str;

 

          /* Find the end of the token. If it is not the end of the string,

           * put a null there. */

          for ( ; *str ; str++ )

                  if ( map[*str >> 3] & (1 << (*str & 7)) ) {

                          *str++ = '/0';

                          break;

                  }

 

          /* Update nextoken (or the corresponding field in the per-thread data

           * structure */

#ifdef _MT

          ptd->_token = str;

#else    /* _MT */

          nextoken = str;

#endif    /* _MT */

 

          /* Determine if a token has been found. */

          if ( string == str )

                  return NULL;

          else

                  return string;

}

 

map[*ctrl >> 3] |= (1 << (*ctrl & 7))说明:

map[*ctrl   >>   3]   |=   (1   <<   (*ctrl   &   7));   

  这句是这样的意思   

      首先map[32]是个uchar型数组,数组每一个是8位,其中每一位可以表示一个字符,32×8=256,这样的话,map[32]中有256个bit,每个bit表示一个ASCII码,那么可以表示256个ASCII码。   

      *ctrl   >>   3,表示将安ascii码,给其分类,*ctrl   >>   3表示,除以8的意思,将ascii每八位分为一组,也就是map[32]中的一个。   

      1   <<   (*ctrl   &   7),这个是这样的意思,7表示为二进制就是00000111,这样的话,相当于是一个数除以8后剩余的余数。1   <<   (*ctrl   &   7),就是将二进制00000001,向右移动(*ctrl   &   7)个位。   

      map[*ctrl   >>   3]   |=   (1   <<   (*ctrl   &   7)),就是表示将map[*ctrl   >>   3]中的(*ctrl   &   7)+1位设为1,表示在该位置查询到一个ascii字符。   

      这样做以后,就相当于简历了一个表,只要查询相应的位是否为1,就知道该字符,在strtok的字符串中是否出现过。

 

;