奇怪的strtok()

jiangtianyin 2009-02-20 07:24:15
刚刚了解到strtok()这个函数,引出几个小问题,问题有点多,言之有理即可得分
1。两个参数的类型是什么,第一个只能是char []而不能是char *对吧?请讲解下两者的区别,比如存储方式等,第二个参数有要求吗?
2。strtok()返回分割符号前面的字符,保存剩下的字符的指针,如果连续两次调用strtok函数会出现什么问题,例如
char str1[] = " ";
char str2[] = "hello world";
char str3[] = "beautiful life";
char *p,*q;
p = strtok(str2,str1);//第一次调用
q = strtok(str3,str1);//第二次调用
现在strtok()保存的到底时str2还是str3后面的字符哦?????
3。一个小程序输出问题
#include<iostream>
#include<string>
using namespace std;

int main()
{
char str[] = "I love C++ program";
char d[] = " ";
cout<<strlen(str)<<endl;
char *p = strtok(str,d);
while (NULL != p)
{
cout<<p<<" "<<strlen(str)<<endl;
p = strtok(NULL,d);
}
return 0;
}

输出结果如下:(为什么后面的strlen()得到的结果是1呢???
18
I 1
love 1
C++ 1
program 1
...全文
237 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
蜥蜴枪王 2011-09-28
  • 打赏
  • 举报
回复
学习~ 原来这个函数自己内部有一个静态指针用来保存剩余的字符串的,我就奇怪 ,为什么MSDN上给出的例子,第二次以后调用时第一个参数会传入一个NULL...
feng4206yu 2009-02-20
  • 打赏
  • 举报
回复

#include <iostream>
#include <string>
using namespace std;

int main()
{
char str[] = "Iwhat love C++ program";
char d[] = " ";
cout <<strlen(str) <<endl;
char *p = strtok(str,d);
while (NULL != p)
{
cout <<p <<" " <<strlen(str) <<endl; //5
p = strtok(NULL,d);
}
return 0;
}


char * __cdecl strtok (
char * string,
const char * control
)

1.strtok的作用是在string中查找control中是否有匹配的字符,即分隔符,如果查找到就会将该字符变为'\0',然后返回该字符段的指针..要注意这样是会改变原字符串的..
2.该函数内部含有一个静态指针nexttoken用来保存第一次使用时即string!=NULL后返回后剩余的一部分字符串...所以如果再使用一次strtok然后将string设为NULL,就会使用nexttoken所指的字符串,即第一次返回后的待tokenize的字符串...
3.至于上面为什么长度是1,是因为'I'后面的空格被替换为了'\0'即结束符,所以strlen(str)的长度永远只是'I'的长度,为1...如果换一个字符串,例如我的例子里面,长度就是5....
waizqfor 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 jiangtianyin 的回复:]
补充一下问题,如果连续调用strtok()好像保存的时后面一个字符窜的后面部分,如果要报两个字符串都分割有什么好办法呢,strtok_r()可以吗
[/Quote]
用strstr函数也可以
waizqfor 2009-02-20
  • 打赏
  • 举报
回复

3。一个小程序输出问题
#include <iostream>
#include <string>
using namespace std;

int main()
{
char str[] = "I love C++ program";
char d[] = " ";
cout < <strlen(str) < <endl;
char *p = strtok(str,d);
while (NULL != p)
{
cout < <p < <" " < <strlen(str) < <endl;
p = strtok(NULL,d);
}
return 0;
}

输出结果如下:(为什么后面的strlen()得到的结果是1呢???
18
I 1
love 1
C++ 1
program 1

为什么strlen()是1 因为你的 strlen(str) 之前
char *p = strtok(str,d);找到了分割符 并把分割符位置填加了'\0'
所以为你计算strlen(str)长度为1
jiangtianyin 2009-02-20
  • 打赏
  • 举报
回复
补充一下问题,如果连续调用strtok()好像保存的时后面一个字符窜的后面部分,如果要报两个字符串都分割有什么好办法呢,strtok_r()可以吗
yuzl32 2009-02-20
  • 打赏
  • 举报
回复
On the first call to strtok, the function skips leading delimiters and returns a pointer to the first token in strToken, terminating the token with a null character. More tokens can be broken out of the remainder of strToken by a series of calls to strtok. Each call to strtokmodifies strToken by inserting a null character after the token returned by that call. To read the next token from strToken, call strtok with a NULL value for the strToken argument. The NULL strToken argument causes strtok to search for the next token in the modified strToken. The strDelimit argument can take any value from one call to the next so that the set of delimiters may vary.
yuzl32 2009-02-20
  • 打赏
  • 举报
回复

char *p = strtok(str,d); //第一次找到分隔符位置并用'\0'填充,所以导致到strlen(str)为1
yuzl32 2009-02-20
  • 打赏
  • 举报
回复
[Quote=引用楼主 jiangtianyin 的帖子:]
为什么后面的strlen()得到的结果是1呢???
[/Quote]
因为你一直在strlen(str)
waizqfor 2009-02-20
  • 打赏
  • 举报
回复

1。两个参数的类型是什么,第一个只能是char []而不能是char *对吧?请讲解下两者的区别,比如存储方式等,第二个参数有要求吗?

char *strtok( char *str1, const char *str2 );
函数返回字符串str1中紧接“标记”的部分的指针, 字符串str2是作为标记的分隔符。如果分隔标记没有找到,函数返回NULL。为了将字符串转换成标记,第一次调用str1 指向作为标记的分隔符。之后所以的调用str1 都应为NULL。

64,691

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧