c语言中strtok函数详解,手把手教你自主实现字符串切割函数,内附详细代码。

article/2025/10/12 14:39:32

函数功能简介:

对字符串str进行切割,切割的标志为字符指针q指向的这两个字符 “# *”;。

但是在对这个函数进行调用时,只有在第一次调用时,才会将str这个字符串的首地址传递过去,后面再进行调用时,str的位置放置的都是NULL。

  那他是如何实现这个功能的呢????我们可以进行调试分析一下。

第一次调用分析

该函数在对字符串进行切割时,会在目的字符串中查找是否有源字符串包含的字符,如果查找到源字符串中包含的字符,就会将这个字符改为‘\0’。,而且返回刚才传递过来的str首地址。并记录这个位置的地址。

下面我们结合内存视角来观察一下  :

刚开始创建完字符数组str后

 执行第一次strtok函数后:

 可以看到,原来放置字符 #的位置被修改为字符‘ \0’。其他的没有任何改变。

示意图如下:

第二次调用分析(中间调用该函数时函数的操作方式)

在进行第一次调用结束时,会记录下被修改成字符  '\0'位置的字符的地址。在第二次进行函数调用时,函数的第一个实参为NULL,这里函数会直接从上一次记录的字符的地址的后一个位置开始进行比对,看是不是还有和源字符串相同的字符,如果有,那就将它修改为 字符0,并返回刚才开始比对的字符的地址。

示意图如下:

最后一次调用分析 

当字符串被切割完成后(遍历到字符串本身的\0)这个时候再次调用strtok函数,函数会直接返回一个空指针。

有了上面的这些特殊位置的函数调用分析,我们就能自己来实现一个strtok函数

自主实现strtok函数 

要注意,该函数有记录功能,所以函数的定义时需要定义一下具有记录功能的变量,在函数结束时依然可以记录数据,所以这里需要定义几个静态区变量。

    static int sz1 = NULL;
    static int count = NULL;
    static char* s1 = NULL;
    static char* s2 = NULL;

总的代码实现如下

#include<stdio.h>
#include<assert.h>
#include<string.h>
//模拟实现strtok  字符串切割函数 
char* my_strtok(char* str1, const char* str2)
{assert(str2);static int sz1 = NULL;static int count = NULL;static char* s1 = NULL;static char* s2 = NULL;int sz = 0;if (str1 != NULL)//说明是第一次进入。{sz1 = strlen(str1);//计算出str1中所有字符的个数s2 = str1;//记录初始地址,等下找到分割符时,将这个地址返回。sz = strlen(str2);for (*str1; *str1 != 0; str1++){			for (int i = 0; i < sz; i++){  if (i == 0){count++;}if (*str1 == *(str2 + i)){*str1 = 0;s1 = str1;//记录这一次置0的位置。return s2;}			 }}}else{s2 = s1+1;	str1 = s2;sz = strlen(str2);for (*str1; *str1 != 0; str1++){			for (int i = 0; i < sz; i++){	if (i == 0){count++;}if (*str1 == *(str2 + i)){*str1 = 0;s1 = str1;//记录这一次置0的位置。return s2;}	}}if (count > sz1){return NULL;}return s2;}}
int main()
{char arr[20] = "12@34.5";char* p = "@.";char* str = NULL;for (str = my_strtok(arr, p); str != NULL; str = my_strtok(NULL, p)){printf("%s\n", str);}return 0;
}

这里需要注意的就是当目的字符串被遍历完成之后,再次调用该函数会返回一个NULL指针。我是以计数器的方式进行实现,每当成功比对一个字符,就进行一次计数,当计数的个数比目的字符串字符个数大时,说明目的字符串被遍历完成了,此时会返回空指针。

 可以看到,实现的结果是符合我们的预期的,如果有更好的算法,可以留言讨论哦!!!!


http://chatgpt.dhexx.cn/article/IcjYBcV4.shtml

相关文章

strtok函数详解 看这一篇就够了-C语言(函数讲解、函数实现、使用用法举例、作用)

strtok()函数用于&#xff1a; 将字符串拆分为标记 函数介绍 函数声明&#xff1a;char * strtok ( char * str, const char * delimiters ); 头 文 件&#xff1a;#include <string.h> 返 回 值&#xff1a; 返回值为char * 类型 。如果找到标记&#xff0c;则为指向…

C/C++字符串函数strtok()详解

函数作用 找到与delimiter相同的地方&#xff0c;将其截断&#xff0c;并返回str 函数理解 第一个参数str是待切割字符串 第二个参数delimiter是分隔符字符串 返回值为char * &#xff0c;一般默认返回str的地址 strtok() 的原理是将查找到与delimiter相同的部分字符串的…

strtok()函数的使用以及注意事项

一、函数的简介 函数原型&#xff1a;char *strtok(char *s, char *delim) 功能&#xff1a;作用于字符串s&#xff0c;以delim中的字符为分界符&#xff0c;将s切分成一个个子串&#xff1b;如果&#xff0c;s为空值NULL&#xff0c;则函数保存的指针SAVE_PTR在下一次调用中将…

strtok()函数

strtok() 将字符串拆分成tokens&#xff0c;tokens是被分隔符中的任何字符分隔的连续字符序列 char* strtok( char* str,const char* sep ); sep参数是个字符串&#xff0c;定义了用作分隔符的字符集合第一个参数指定一个字符串&#xff0c;它包含了0个或者多个由sep字符串中一…

strtok函数的基本使用

strtok函数的基本使用 一、功能及解释&#xff1a;strtok函数的简单运行strtok函数的基本使用 strtok的函数原型&#xff1a; char* strtok (char* str, const char* sep) 一、功能及解释&#xff1a; 1.包含在string.h头文件中 2.sep是个字符串&#xff0c;定义了用作分隔符…

关于函数strtok和strtok_r的使用要点和实现原理(一)

strtok函数的使用是一个老生常谈的问题了。该函数的作用很大&#xff0c;争议也很大。以下的表述可能与一些资料有区别或者说与你原来的认识有差异&#xff0c;因此&#xff0c;我尽量以实验为证。交代一下实验环境是必要的&#xff0c;winxpvc6.0&#xff0c;一个极端平民化的…

strtok函数

头文件 string.h 函数声明 char * strtok &#xff08;char * str&#xff0c;const * sep&#xff09; 返回值 分隔符之前字符串的首地址 用法 sep的参数是个字符串&#xff0c;定义了用作分隔符的字符集合str指定一个字符串&#xff0c;它包含了一个或多个sep中分隔符分割的…

C语言strtok()函数详解

函数原型 char *strtok(char *str, char const *sep);第一次调用strtok函数时,这个函数将忽略间距分隔符并返回指向在str字符串找到的第一个符号的指针,丢掉分隔符sep,添加NULL字符结尾&#xff08;可以理解为用NULL替换了sep&#xff09;. 通过调用一系列的strtok函数,更多的…

数据库面试题——内连接与外连接、左连接与右连接的区别

内连接与外连接的区别: 1、连接结果不同 内连接的连接结果仅包含符合连接条件的行&#xff0c;参与连接的两个表都必须符合连接条件&#xff1b;而外连接的连接结果不仅包含了符合连接条件的行&#xff0c;同时还包括不符合自身条件的行&#xff0c;其中还包括左外连接、右外连…

sql中内连接和外连接的区别

对于两张表&#xff0c;外连接和内连接的区别在于&#xff1a; 内连接&#xff1a;只显示两表id匹配的左外连接&#xff1a;显示join左边的表的所有数据&#xff08;不管两表是否匹配&#xff09;&#xff0c;对于不匹配的部分都用NULL显示右外连接&#xff1a;与左外连接相反…

左连接 ,右连接,内连接和全外连接的4者区别

基本定义&#xff1a; left join &#xff08;左连接&#xff09;&#xff1a;返回包括左表中的所有记录和右表中连接字段相等的记录。 right join &#xff08;右连接&#xff09;&#xff1a;返回包括右表中的所有记录和左表中连接字段相等的记录。 inner join &#xff08;等…

数据库中的内连接、自然连接和外连接的区别

数据中的连接join分为内连接、自然连接、外连接&#xff0c;外连接又分为左外连接、右外连接、全外连接 当然&#xff0c;这些分类都是在连接的基础上&#xff0c;是从两个表中记录的笛卡尔积中选取满足连接的记录。笛卡尔积简单的说就是一个表里的记录要分别和另外一个表的记…

交叉连接、内连接和外连接的区别及使用方式

一、交叉连接、内连接、外连接的区别 交叉连接又叫’笛卡尔积’&#xff0c;它是指不使用任何条件&#xff0c;直接将一个表的所有记录和另一个表中的所有记录一一匹配。内连接 则是只有条件的交叉连接&#xff0c;根据某个条件筛选出符合条件的记录&#xff0c;不符合条件的记…

内连接与外连接区别

内连接&#xff1a;指连接结果仅包含符合连接条件的行&#xff0c;参与连接的两个表都应该符合连接条件。 外连接&#xff1a;连接结果不仅包含符合连接条件的行同时也包含自身不符合条件的行。包括左外连接、右外连接和全外连接。 左外连接&#xff1a;左边表数据行全部保留…

mysql 内连接、自然连接、外连接的区别

数据库中的内连接、自然连接、外连接 注意&#xff1a;mysql不支持全外连接&#xff0c;using和on的区别在于需要连接的两个表的属性名相同的时候使用using和on效果一样&#xff0c;而属性名不同的时候必须使用on 数据库中的连接join分为内连接、自然连接、外连接&#xff0c…

mysql 自然连接、内连接、外连接的区别

数据库中的连接join分为内连接、自然连接、外连接&#xff0c;外连接又分为左外连接、右外连接、全外连接(注意&#xff1a;mysql不支持全外连接) 首先&#xff0c;我们先来建两张表&#xff0c;第一张表命名为kemu&#xff0c;第二张表命名为score&#xff1a; 一、left join…

内连接与外连接的区别

有两个表A和表B。表A结构如下&#xff1a;Aid&#xff1a;int&#xff1b;标识种子&#xff0c;主键&#xff0c;自增IDAname&#xff1a;varchar数据情况&#xff0c;即用select * from A出来的记录情况如下图1所示&#xff1a;图1:A表数据表B结构如下&#xff1a;Bid&#xf…

内连接、左外连接与右外连接的区别及作用介绍

SQL语句当中比较难的部分就有今天要给朋友们分享的这个&#xff0c;inner join, left join 和 right join他们三个的作用以及区别是什么。 顺便也会把交叉连接一起分享了。 上面会分享一些基本的语法与使用&#xff0c;下方会详细介绍 1&#xff09;交叉连接&#xff0c;又称笛…

图解数据库左连接、右连接、内连接、外连接、全连接的区别

数据库连表方式 内连接 &#xff1a;inner 、inner join外连接 &#xff1a;outer join 左外连接 &#xff1a;left outer join左连接 &#xff1a;left join右外连接 right outer join右连接&#xff1a; right join 全连接 full join 、union 准备 现在有2张表&#xff0c…

内链接和外连接的区别

内连接&#xff0c;也被称为自然连接&#xff0c;只有两个表相匹配的行才能在结果集中出现。返回的结果集选取了两个表中所有相匹配的数据&#xff0c;舍弃了不匹配的数据。由于内连接是从结果表中删除与其他连接表中没有匹配的所有行&#xff0c;所以内连接可能会造成信息的丢…