遇到关于strtok的一个问题,郁闷了好一会儿终于找到答案

来源:互联网 发布:淘宝摄影室内布光 编辑:程序博客网 时间:2024/04/27 22:33

今天用这个函数用的郁闷了好一会儿,就是因为字符串是用的test2指针形式,而没有用test1那样的数组形式!

下面是我在网上看到的:

int main() {

char test1[] = "feng,ke,wei";

char *test2 = "feng,ke,wei";

char *p; p = strtok(test1, ",");

while(p)

{   

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

p = strtok(NULL, ",");   

}

return 0;

}

运行结果:

feng

ke

wei

但如果用p = strtok(test2, ",")则会出现内存错误,这是为什么呢?是不是跟它里面那个静态变量有关呢? 我们来看看它的原码:

/****strtok.c - tokenize a string with given delimiters**         Copyright (c) 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.*       //这里已经说得很详细了!!比MSDN都好! *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;                        //将函数第一参数设置为NULL时调用的余串
#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;                                    //此时的string返回余串的执行结果 
          /* Find the end of the token. If it is not the end of the string,           * put a null there. */
//这里就是处理的核心了, 找到分隔符,并将其设置为'\0',当然'\0'也将保存在返回的串中          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;