strtok函数的实现(分步详细解释配图)

目录

函数大概的运行实现

1.定义一些变量 

2.开始的一些条件

3.去掉pc前面一些需要被剪掉的字符

 4.返回值ret的初始化   

5.找到下一个分隔符

 5.补\0

6.结束返回

完整代码


头文件:#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;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值