前言:在本章,将介绍如何通过strtok函数来分隔字符串。
问:现有一段字符串
"[email protected]"
,如何才能将@
.
去掉打印出剩下的部分呢?
下面将先介绍strtok函数。
strtok
功能:通过指定的分隔符拆分字符串。
splusplus对其介绍如下:(只选取了参数部分,重点我将在下面讲解)
strtok有2个参数,第二个参数
delimiters
(分隔符)是个字符串,定义了用作分隔符的字符的集合,第一个参数str
指定一个字符串,它包含了0个或多个由delimiters字符串中一个或者多个分隔符的标记。strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可以修改。(不要写成常量字符串,因其不可修改)
1.strtok函数找到str中的下一个标记,并将该标记用\0
结尾,然后返回一个指向该标记的指针。
2.strtok函数的第一个参数不为NULL,函数将找到str中的第一个标记,strtok函数将保存它在字符串中的位置.
3.strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记
4.在第一次调用时,该函数需要一个C字符串作为字符串,其第一个字符用作扫描标记的起始位置。在随后的调用中,该函数需要一个空指针,并使用最后一个标记末尾之后的位置作为扫描的新起始位置。
ps:黄色部分为理解strtok函数的重点,第一点为strtok函数的工作原理,第2第3点则是strtok函数的两种不同的情况.
下面我将通过一段代码循序渐进的深入讲解上面3点
1.
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "[email protected]"; //指定字符串
char arr[30];
strcpy(arr, str); //拷贝一份临时的指定字符串,以避免改变str
char* p = "@."; //指定的分隔符(标记)
char* tmp = strtok(arr, p); //使用一次strtok,因其返回的是一个指针,所以用字符指针接收
printf("%s\n", tmp); //会打印出什么呢?
return 0;
}
打印结果如下:
解释:上文黄色部分第一点提过:1.strtok函数找到str中的下一个标记,并将该标记用
\0
结尾,然后返回一个指向该标记的指针.
2.
代码并未完结,我们往下续写:
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "[email protected]"; //指定字符串
char arr[30];
strcpy(arr, str); //拷贝一份临时的指定字符串,以避免改变str
char* p = "@."; //指定的分隔符(标记)
char* tmp = strtok(arr, p);
printf("%s\n", tmp);
//以下为续写部分
tmp = strtok(NULL, p); //此时的第一个参数为NULL,为什么呢?
printf("%s\n", tmp); //打印如何?
return 0;
}
此时的打印结果如下:
到这里,有人或许会有以下2点疑问:
1.为什么传的是空指针呢?
2.第一个参数传了空指针,那strtok是怎么还能找到我后面的内容的呢?
下面对它们逐个解释:
第一点:我们之前使用过了一次strtok函数,它对标的是黄色部分的第4点:在第一次调用时,该函数需要一个C字符串作为字符串,其第一个字符用作扫描标记的起始位置。在随后的调用中,该函数需要一个空指针,并使用最后一个标记末尾之后的位置作为扫描的新起始位置。
第二点:对标的是黄色部分的第2第3点:2.strtok函数的第一个参数不为NULL,函数将找到str中的第一个标记,strtok函数将保存它在字符串中的位置. 3.strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标记 第2点后半句strtok函数将保存它在字符串中的位置
,而第3点后半句strtok函数将在同一个字符串中被保存的位置开始,查找下一个标记
. 我们知道:函数是在栈区创建了=的,出了栈区就会立即销毁,而strtok函数却拥有记忆功能(出了栈区也未被销毁),这不正与static的作用相同吗?
3.
最后的步骤与第二步差不多,参数都是空指针
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "[email protected]"; //指定字符串
char arr[30];
strcpy(arr, str); //拷贝一份临时的指定字符串,以避免改变str
char* p = "@."; //指定的分隔符(标记)
//1
char* tmp = strtok(arr, p);
printf("%s\n", tmp);
//2
tmp = strtok(NULL, p);
printf("%s\n", tmp);
//以下为续写部分
tmp = strtok(NULL, p); //与第二步步骤相同
printf("%s\n", tmp);
return 0;
}
此时的打印结果如下:
至此,文章开头提出得问题视乎得到了解决?但是上述代码仅为方便读者理解才这样写的.
不知读者们有没有思考以下问题:
上面是有3个分隔符,所以我们用了3次strtok,但若是标记数量不是3个呢?
比如"[email protected]@hi.jk"
这里面就有四个分隔符(假定分隔符为@.
).难道我们要一直重复写下去?
4.最终修改(文章核心代码呈现,上文看不明白的朋友记住以下如何用的即可)
将通过一个for循环达到目的
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "[email protected]"; //指定字符串
char arr[30];
strcpy(arr, str); //拷贝一份临时的指定字符串,以避免改变str
char* p = "@."; //指定的分隔符(标记)
char* tmp = NULL; //创建一个字符指针变量
for (tmp = strtok(arr, p); *tmp != NULL; tmp = strtok(NULL, p))
{
printf("%s\n",tmp);
}
return 0;
}
for循环的第一个初始条件为strtok(想拆分的字符串,分隔符),
第3个调整条件为strtok(NULL,分隔符), 因为只有在第一次使用strtok时第一个参数才为想拆分的字符串,其后使用strtok第一个参数都是NULL,
第2个判断条件为*tmp!=NULL,读取到最后没有字符,则判断条件不成立,那么停止循环.
文末BB:对哪里有问题的朋友,可以在评论区留言,若哪里写的有问题,也欢迎朋友们在评论区指出,博主看到后会第一时间确定修改。最后,制作不易,如果对朋友们有帮助的话,希望能给点点赞和关注.