目录
分隔函数 strtok
函数原型:
char * strtok ( char * str, const char * sep);
参数:
- str—要被分解的字符串
- sep—用作分隔符的字符(可以是一个,也可以是集合)
返回值:
- 该函数返回被分解的第一个子字符串,若无可检索的字符串,则返回空指针
代码演示:
输出结果:
函数解析:
- strtok的参数中,sep表示的其实是一个分隔符的合集。
- strtok 会把字符串中的分隔符当作一个标记,同时会把标记变为\0
- 同时会返回标记位置之前(或者是标志位置之前,前一个标记位置之后)的一个字符串。
- 同时strtok会改变原先的字符串,因为分隔符变成了\0
- 当把一个标记变成\0后,strtok会记录这个标记的位置,并且在这个标记往后,继续往下寻找是否有在sep记录中的标记,也因此,在第一次使用strtok时,第一个参数是需要分隔的字符串,当第二次还是针对该字符串使用时,strtok的第一个参数变成了NULL,其余往后的也同样是NULL
注意事项:
(1)sep
- 很多人在使用strtok的时候会放不开手脚,因为他们认为strtok的分隔符只有一个,但是sep是一个分隔符的集合,也就是说,我们设置一个字符串:hello@world.com 我们可以设置sep为 "@.",这样一个合集,当strtok在字符串中寻找标记时,是寻找字符串中是否有和sep内部字符相配符号。
(2)分隔符可不可以出现在第一个字符?
- 答案是:可以
当strtok分解的字符串首字符就是分隔符,那么strtok()会忽略首个分隔符,直接从第二个分隔符往下继续分解,例如:@hello@world.com 那么strtok()会忽略第一个@,还是以hello@world.com 的字符串形式继续分解。
(3)因为是分隔符号被\0代替, 所以直接打印只能出现\0前一段的字符串
- 例如:char arr = "hello@world.com "我们设置sep为 "@.",这样一个合集,当我们直接进行printf("%s\n",arr)我们得到的只是hello
(4)stroke只有第一次使用时会返回起始位置
int main()
{
char arr[] ="hello@world.com";
char buf[30] = { };
strcpy (buf , arr);//拷贝字符串,不改变原字符串
char* p ="@.";
char *s = strtok(buf , p);//对字符串进行分隔
printf("%s\n", s);//打印出hello
s = strtok (NULL, p);//原分隔符@变成了\0,从\0的位置开始再度分隔
printf("%s\n", s);//二度打印,得到world
s = strtok (NULL, p);//原分隔符.变成了\0,从\0的位置再度分隔
printf("%s\n", s);//三度打印,得到com
return 0;
}
- 根据上一个注意事项,我们得到stroke使用后直接按照%s打印原字符串变量名,得到的结果只有第一次被代替成\0之前的字符。,若我们要将所有的除去分隔符后的所有字符都打印出来,只能遵循以上代码或者下面的代码逻辑进行打印。
优化:
int main()
{
char arr[] ="hello@world.com";
char buf[30] = { };
char* r = NULL;
for (r = strtok(buf, p); r != NULL; r = strtok(NULL, p))
{
printf("%s\n",r);
}
return 0;
}
for (r = strtok(buf, p); r != NULL; r = strtok(NULL, p))
- r!=NULL 指的是字符串结束了就自动打破循环
- r=strtok(buf,p)指的是第一次返回被分隔切割后的字符串
- r=strtok(NULL,p)指的是第一次以外的返回被分隔符切割的字符串。