1. 用法
1. 声明:char *strtok(char *str, const char *delim)
- str -- 要被分解成一组小字符串的字符串。第一次调用 strtok() 时,这个参数应该是你想要分割的字符串。随后的调用应该将此参数设置为
NULL
,以便继续从上次的位置分割。- delim -- 包含分隔符的 C 字符串。
2. 作用:strtok() 用于将字符串分割成一系列的子串
3. 返回值:该函数返回被分解的第一个子字符串,如果没有可检索的字符串,则返回一个空指针。
贝蒂说:“如果一下子没有明白,不要但心,继续跟着贝蒂看看例子就明白啦~”
2. 实例
#include <string.h>
#include <stdio.h>
int main()
{
char str[80] = "This is - betty -@class";
const char s[] = "-@";
char* p = strtok(str, s);//第一次传参
while (*p != NULL)
{
printf("%s\n", p);
p = strtok(NULL, s);//非第一次传参
}
return 0;
}
输出结果:
This is
betty
class
简单来说:“strtok()就是把从目标字符串中,以分隔符为标志,将其分成若干个子串,并且需要多次调用”
3. 实现
思路分析:
第一步:
先判断是否为第一次传入
第二步:
分割起始的分割符,我们先假设需要在“@+abc”中切割“@+”
1. 首先判定p1中首元素是否需要切割(在p2中排查直到遇见‘\0’)。
2. 如果匹配成功,让pp+1指向下一个元素,让p3重新指向p2的首元素,继续排查下一个元素。
3. 如果排查失败,p2或pp指向‘\0’,如果p2指向'\0',说明起始位置的分割符排查成功,如果pp指向‘\0’,说明没有再分割的字符串,返回NULL。
assert(p2);//防止p2为空指针
static char* pp= NULL;//static修饰,延长其生命周期
//让其第二次调用时后能指向下一个字符串
char* ret = NULL;//作为返回值
char* p3 = (char*)p2;//记录p2的初始位置
if (p1 != NULL)
{
pp = p1;//第一次传入
}
while (*pp && *p2)//排除起始的分割符
{
if (*p2 == *pp)
{
pp++;
p2 = p3;//成功找到再重新匹配
}
else
{
p2++;//匹配下一个字符
}
}
第三步:
分割后续字符串,我们假设在“ab@cd”中分割“@”。
ret = pp;//记录初始位置,方便返回
p2 = p3;//让p2指向初始位置
while (*pp && (*pp!= *p2++))//开始匹配
{
if (*p2=='\0')
{
pp++;//判断下一个字符
p2 = p3;//让p2重新开始匹配
}
}
if (*pp)//判断是不是'\0'
{
*pp++ = '\0';//分割字符串,并指向下一个字符
}
return ret;
第四步:
当非第一步传入时,*pp==‘\0’时,说明分割结束,返回NULL.
if (p1 == NULL && pp=='\0')//查找完毕
{
return NULL;//最后返回空指针
}
完整代码:
#include <assert.h>
#include <stdio.h>
char* my_strtok(char* p1, const char* p2)
{
assert(p2);//防止p2为空指针
static char* pp= NULL;//static修饰,延长其生命周期
//让其第二次调用时后能指向下一个字符串
char* ret = NULL;//作为返回值
char* p3 = (char*)p2;//记录p2的初始位置
if (p1 == NULL && pp=='\0')//查找完毕
{
return NULL;//最后返回空指针
}
if (p1 != NULL)
{
pp = p1;//第一次传入
}
while (*pp && *p2)//排除起始的分割符
{
if (*p2 == *pp)
{
pp++;
p2 = p3;//成功找到再重新匹配
}
else
{
p2++;//匹配下一个字符
}
}
if (*pp = '\0')
{
return NULL;//第一次排查指向'\0'
}
ret = pp;//记录初始位置,方便返回
p2 = p3;//让p2指向初始位置
while (*pp && (*pp!= *p2++))//开始匹配
{
if (*p2=='\0')
{
pp++;//判断下一个字符
p2 = p3;//让p2重新开始匹配
}
}
if (*pp)//判断是不是'\0'
{
*pp++ = '\0';//分割字符串,并指向下一个字符
}
return ret;
}
贝蒂说:“这应该算是字符串函数最难实现的吧,贝蒂思考了好久的说~”