前言
strtok
函数的作用是比较独特的,可以用来对字符串进行分割,对于我们获取命令或者数据集合后的数据处理是不可或缺的一步。但是详细介绍 strtok
的博文很少,而且linux手册的介绍也比较简单,这边写篇博文记录一下学习到的这个函数的用法。
一、strtok函数是什么?
函数定义如下:文章来源:https://www.toymoban.com/news/detail-656501.html
strtok()函数,将字符串分解为一组字符串
声明:
char *strtok(char *str, const char *delim);
头文件:#include <string.h>
参数:
str: 源字符串指针,即分割之前的字符串
delim: 用于分割的字符串指针,即分割符号。如:空格" "、 逗号","、 字符集合"@."等
返回值:
成功:返回指向被分割出片段的指针
NULL:没有可被分割的字符串
即从字符串 str
中查找标记 delim
中出现的字符并以此切割字符串。注意原字符串 str
在函数调用完成后也会发生变化,变成分割后的第一个字符串。因此不能向第一个参数传递字符串常量,错误写法: char * str = "gonna be a string"
,应写成:char str[] = "gonna be a string"
。
二、字符串分割的步骤
在使用 strtok
函数时,第一次调用需要给定 str
参数的值,往后的每一次调用只需将 str
参数设置为 NULL
即可。我们通常使用 while
循环自动分割字符串的所有字符
- 第一个参数不是
NULL
时,strtok
函数查找str
下一个标记,以\0
结尾,strtok
函数会保存标记的地址。 - 第一个参数为
NULl
时,strtok
函数取上次分割字符串后剩余的字符串继续进行分解操作,如果没有更多的标记则返回NULL
。
来举个例子:
#include <stdlib.h>
#include "stdio.h"
#include "string.h"
int main() {
char *temp = NULL;
char input[128] = "#10?-ssid=test&-passwd=12345678&-netmask=255.255.255.0&-gateway=192.168.1.1";
//char *input = (char *)malloc(128);
//scanf("%s",input);
printf("%s\n",input);
temp = strtok(input,"?&");
printf("input=%s,temp=%s\n", input, temp);
while(temp != NULL){
temp = strtok(NULL,"?&");
printf("input=%s,temp=%s\n", input, temp);
};
return 0;
}
输出结果:
#10?-ssid=test&-passwd=12345678&-netmask=255.255.255.0&-gateway=192.168.1.1
input=#10,temp=#10
input=#10,temp=-ssid=test
input=#10,temp=-passwd=12345678
input=#10,temp=-netmask=255.255.255.0
input=#10,temp=-gateway=192.168.1.1
input=#10,temp=(null)
可以看到,我们传入的字符串以参数 delim
为依据对字符串进行了切割,其实就是把字符串 str
在参数 delim
中出现的字符替换成了 \0
,并且返回标记字符串的首地址,了解到这一点,那么就可以使用 strtok(NULL,' ');
对字符串进行分离输出了。我们把该字符串分割的情况用图像展示出来,可以看到分割的依据是参数 delim
中的 每一个字符:
所以在第一次分割后,str
的值会变成 #10
,而后续的字符串需要我们用循环 strtok(NULL," ");
直至值为 NULL
来依照顺序把字符串提取出来。
char *
strtok (char *s, const char *delim)
{
static char *olds;
return __strtok_r (s, delim, &olds);
}
char *
__strtok_r (char *s, const char *delim, char **save_ptr)
{
char *end;
if (s == NULL)
s = *save_ptr;
//...
}
通过源码可以看到,其实 strtok
函数是把分割后剩余的字符串存储在了静态变量中,当函数的第一个参数传入 NULL
时再提取出来进行分解。因为 static
静态变量是全局变量,这种方式在多线程操作时或发生中断的情况下容易引起冲突,所以Linux中可以使用更加安全的 strtok_r
函数进行替换。
三、替代方案:strtok_r函数
strtok
函数是一个线程不安全的函数,多线程时,linux下可以用 strtok_r
函数代替,该函数与 strtok
相似,主要是多了第三个参数 saveptr
。
函数定义如下:
strtok_r()函数,将字符串分解为一组字符串,同时保证线程安全
声明:
char *strtok_r(char *str, const char *delim, char **saveptr);
头文件:#include <string.h>
参数:
str: 源字符串指针,即分割之前的字符串
delim: 用于分割的字符串指针,即分割符号。如:空格" "、 逗号","、 字符集合"@."等
saveptr: 保存分割后剩余的字符串
返回值:
成功:返回指向被分割出片段的指针
NULL:没有可被分割的字符串
该函数的第三个参数 saveptr
使用用户传入的指针重新申请变量来保存剩余的字符串,更好的保存了切分时的上下文,因此该函数就能被中断而不担心会丢失数据,并且变量保存在每个函数自己的栈,因此可以同时运行该函数的多个副本,在并行环境中保证了安全性。文章来源地址https://www.toymoban.com/news/detail-656501.html
到了这里,关于C语言 strtok字符串分割函数详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!