目录
头文件:#include <string.h>
定义函数:char * strtok(char *s, const char *sep);
函数说明:strtok()用来将字符串分割成一个个片段。参数s 指向欲分割的字符串,参数sep 则为分割字符串,当strtok()在参数s 的字符串中发现到参数sep 的分割字符时则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s 字符串,往后的调用则将参数s 设置成NULL。每次调用成功则返回下一个分割后的字符串指针。
返回值:返回下一个分割后的字符串指针,如果已无从分割则返回NULL。
函数大概的运行实现
char arr1[] = "@@@abc*eo@*@@wbesh##";
char arr2[25] = { 0 };
strcpy(arr2, arr1);
char* sep = "*@#";
char* ret = 0;
char* p = arr2;
for(ret = My_strtok(p, sep); ret != NULL; ret = My_strtok(NULL, sep))
printf("%s\n", ret);
执行后的结果为:
接下来为大家分步解释
1.定义一些变量
char* My_strtok(char* p1, const char* p2)
p1:目标字符串(被切割)p2:sep(分割符的集合)
assert(p2);
static char* pc = NULL;
char* ret = NULL;
char* p3 = (char*)p2;
pc:静态变量,用来标记,作用于p1 ret:返回值 p3:拷贝p2的初始位置
assert(p2) 防止p2=NULL
2.开始的一些条件
if (p1 == NULL && !*pc)
return NULL;
if (p1 != NULL)
pc = p1;
第一个if判断是不是已经无从分割,无从分割时,pc指向\0,如果是就返回NULL
第二个if判断是否为第一次分割,因为第一次分割传参p1=字符串地址,第一次赋值,接下来都是p1=NULL;
3.去掉pc前面一些需要被剪掉的字符
while (*pc && *p2)//去掉前面要被剪掉的
if (*p2 == *pc)
{
pc++;
p2 = p3;
}
else
p2++;
列如:目标字符串@@@abc... 这里abc前面的字符都是需要跳过的
只要满足*pc==*p2 ,pc就会++指向下一个,并且p2=p3,p2重新指向第一个
如果*pc!=*p2,p2就会++指向下一个,直到p2=\0
如果p2=\0 while(*p2)条件就不满足跳出来,这个时候pc就是要被返回的第一个字符
如果pc里面没有可以被返回的字符就会一直++然后while(*pc)跳出循环
是不是很妙
4.返回值ret的初始化
ret = pc;//初始化
p2 = p3;
这里很好理解
5.找到下一个分隔符
while (*pc && *pc != *p2++)//确定标记点
if (!*p2)
{
pc++;
p2 = p3;
}
*pc != *p2++ :这个的意思是如果满足 *pc != *p2 这个条件 之后p2++
if(!*p2) 每次当*p2=\0就执行 当p2指向\0,pc指向下一个,p2指针初始化
如果*pc == *p2 或者pc指向\0 跳出循环
5.补\0
if (*pc)//判断是不是最后的点
*pc++ = '\0';
如果pc指向的是*@#这一类的分隔符,*pc=‘\0',然后pc++指向下一个
如果pc指向\0,不操作,这样子就可以通过pc是否指向\0判断是不是无可分割,和第一步呼应
6.结束返回
return ret;
完整代码
char* My_strtok(char* p1, const char* p2)
{
assert(p2);
static char* pc = NULL;
char* ret = NULL;
char* p3 = (char*)p2;
if (p1 == NULL && !*pc)
return NULL;
if (p1 != NULL)
pc = p1;
while (*pc && *p2)//去掉前面要被剪掉的
if (*p2 == *pc)
{
pc++;
p2 = p3;
}
else
p2++;
ret = pc;//初始化
p2 = p3;
while (*pc && *pc != *p2++)//确定标记点
if (!*p2)
{
pc++;
p2 = p3;
}
if (*pc)//判断是不是最后的点
*pc++ = '\0';
return ret;
}