我们知道strtok是一个字符串切割函数,先来了解一下它
原型: char *strtok(char *str, const char *delim);
功能:分解字符串为一组字符串。
参数说明:str为要分解的字符串,delim为分隔符字符串。
原理:找到分隔符,并用'\0'代替,即字符串的结束符。
返回值:从str开头开始的一个个被分割的串。当没有被分割的串时则返回NULL。
再看一个简单应用
//借助strtok实现split
#include <string.h>
#include <stdio.h>
int main()
{
char s[] = "Hello world,engineers!~";
const char *d = " ,!";//以空格,逗号和感叹号作为分隔符,注意是可以取多个的
char *p;
p = strtok(s,d);
while(p)
{
printf("%s\n",p);
p=strtok(NULL,d);
}
return 0;
}
要特别注意的是函数的参数类型以及返回类型。
每次切割返回的是char*型的;被切割的字符串是char数字型的;切割符是const char*型的。如果被切割字符串是string类型的,可以用(char*)str.data()进行类型转换。
但有两个坑是不得不说的问题
坑1、函数在循环执行的时候必须先将返回值记录下来,再进行切割否则就会出现空指针的问题。
那么原因是什么呢?再让我们详细了解一下strtok函数的原理:
函数strtok保存string中标记后面的下一个字符的指针,并返回当前标记的指针。
第一次调用时候,strtok函数从不是分隔符的第一个字符开始搜索,找到第一个是分隔符为止,将其替换为‘\0’作为结束。但是函数此时已经保存了分隔符之后的那个字符,因此
后续再调用strtok时,第一个参数为NULL,继续将string标记化(切割)。NULL参数表示调用strtok继续从string中上次调用 strtok时保存的位置开始标记化。
如果调用strtok时已经没有标记(分隔符),则strtok返回NULL。这就是问题所在了哦!!!
如果你在while中先执行strtok函数,再打印。那么切割到最后函数返回为NULL的时候,再赋值就会出现空指针的问题。如果非要先切割再打印的话可以在打印之前做一个null判断。
坑2、还要注意strtok会修改输入字符串,如果调用strtok之后还要在程序中使用这个字符串,则应复制这个字 符串。
想尝试的人可以在上述程序中第一次切割之后打印一下s,会发现它已经变成了被切割下来的第一个东西。因此每执行一次strtok,都会改变原来的字符串。因为它将分隔符转换为‘\0’了,字符串从这里就断掉了。