您的位置:首页 > 理论基础 > 计算机网络

有关strtok函数进行字符串分割

2011-11-22 17:20 567 查看
最近读别人代码时,用到strtok函数进行字符串分割。其中有几个疑问:

1、为什么第一次调用时,第一个参数是原字符串,之后第一个参数是NULL即可。

2、第二个参数如果是字符串,而不是字符,那结果怎样?

3、该函数有什么限制因素。

故进行了学习。。。。。

查函数库看到的strtok的解释和示例:

strtok
Syntax:
#include <cstring> char *strtok( char *str1, const char *str2 );

 

The strtok() function returns a pointer to the next "token" instr1, where
str2 contains the delimiters thatdetermine the token. strtok() returns
NULL
if notoken is found. In order to convert a string to tokens, the firstcall to strtok() should have
str1 point to the string tobe tokenized. All calls after this should have
str1 beNULL.

For example:

 char str[] = "now # is the time for all # good men to come to the # aid of their country";

   char delims[] = "#";

   char *result = NULL;

   result = strtok( str, delims );

   while( result != NULL ) {

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

       result = strtok( NULL, delims );

   }            

The above code will display the following output:

  result is "now "

   result is " is the time for all "

   result is " good men to come to the "

   result is " aid of their country"

下面是查到的网络文章对源码的解释:

原型:char * strtok(char * s,const char * ct)
用途:在s中找出以ct中的字符为分隔的字符串,即是源串中除去了含有分隔串中的所有字符后余下的一段段的字符串,每调用一次找到一串,找不到则返回空串。第一次调用必须传给它有效的字符串,第二次传NULL就可以了,每次调用返回找到的子串的时候都会把源串中该子串的尾部字符(原来是搜索串中的某一字符)修改成'/0'字符返回值为每次调用得到的字串。
下面看一下它的使用

 char sbody[]="Presetptz/r/nPreset1=hello/r/nPreset2=ttttt/r/nend/r/n";

///char *pbody="Presetptz/r/nPreset1=hello/r/nPreset2=ttttt/r/nend/r/n";//errror

 char except[] = "12/r/n";     //以‘1’,‘2’,‘/r’,‘/n’任一个字符分割

 char *ptoken = NULL;

 ptoken = strtok(sbody,except);

 while(NULL!=ptoken)

 {

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

  ptoken = strtok(NULL,except);

 }

 输出为:
  Presetptz

  Preset

  =hello

  Preset

  =ttttt

  end
下面我们看一下它的源码:

char*___strtok;    //关键这个全局指针变量

char * strtok(char * s,const char *ct)

{

 char *sbegin, *send;

 

 sbegin  = s ? s :___strtok;//不等于NULL用原始字符串,否则用___strtok

 if (!sbegin) {

  return NULL;//结尾

 }

 sbegin += strspn(sbegin,ct);//

 if (*sbegin == '/0') {

  ___strtok = NULL;

  return( NULL );

 }

 send = strpbrk( sbegin, ct);

 if (send && *send!= '/0')

  *send++ = '/0';

 ___strtok = send;

 return (sbegin);

}

其中:  ssize_t strspn(const char*s,char*accept)// 返回accept中任一字符在s中第一次出现的位置

char * strpbrk(const char * cs,const char *ct)//返回指向ct中任一字符在cs中第一次出现的位置

这个不能有两个线程同时使用strtok否则就会出现错误。函数不难分析,___strtok指针指向除去第一个有效字串后面的位置,到这里我们应该清楚为什么第二次调用时只要传NULL就可以了,当然这里也暴露了它的缺点,就是说同时,对于strtok函数第二个参数可以是个字符串,但如果是字符串的话,则对字符串中任意一个字符都当做是分割符。还有就是我在使用这个函数时碰到的问题,如上面的代码如果我把sbody换成pbody,则编译没有问题,运行时就会出错,为什么?还是自己的基本功不扎实,pbody在是个静态字符串,说白了,它是在编译时就已经赋值而且相当于是一个const常量,不能被修改,而strtok是需要修改字符串的,所以产生问题不足为奇。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息