天天看點

strtok函數的實作

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;

      }

源碼:

#include <cruntime.h>

#include <string.h>

#ifdef _MT

#include <mtdll.h>

#endif    

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    

          static char *nextoken;

#endif    

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

                  map[count] = 0;

          do {

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

          } while (*ctrl++);

          if (string)

                  str = string;

          else

#ifdef _MT

                  str = ptd->_token;

#else    

                  str = nextoken;

#endif    

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

                  str++;

          string = str;

          for ( ; *str ; str++ )

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

                          *str++ = '/0';

                          break;

                  }

#ifdef _MT

          ptd->_token = str;

#else    

          nextoken = str;

#endif    

          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的字元串中是否出現過。