C库函数 ——strstr、strtok的详解

2023-05-16

💌内容专栏:【C语言】进阶部分

💌本文概括:理解C语言库函数strstr、strtok的功能。

💌本文作者:花 碟

💌发布时间:2023.3.14

目录

一、C库函数strstr()

1.函数声明

2.参数设置

3.返回值

4.函数的使用

5.模拟实现strstr函数

5.1思路分析

5.2 代码实现

 二、C库函数strtok

1.函数声明

2.规则

3.代码使用


 

一、C库函数strstr()

1.函数声明

char * strstr (const char * str1,const char * str2)

char * strstr ( const char * str1,const char * str2),函数的具体功能是在字符串 str1 中查找第一次出现字符串 str2 的位置,不包含终止符 '\0' 

2.参数设置

str1: 要被查找的字符串

str2: 在str1中要被搜索的字串

3.返回值

该函数返回在 str1中第一次出现 str2 字符串的位置,如果未找到则返回 NULL 指针

4.函数的使用

#include <stdio.h>
#include <string.h>
 
int main()
{
     char arr1[20] = "abcdefghi";
     char arr2[10] = "defghi";
 
    char* ret = strstr(arr1, arr2);
 
    if(ret == NULL)
        printf("没找到\n");
    else
       printf("%s\n", ret);
   
   return 0;
}

5.模拟实现strstr函数

5.1思路分析

如果说要在abbbcdef 中查找 bbc,我们首先想到的是,str1指向首字符'a',str2指针指向首字符'b',让str1与str2指针进行比较。首先str1指向的第一个字符,并不一定与str2指向的第一个字符相等,此时我们让str1向后移动,当str1指向的字符正好与str2指针指向的字符一致时,我们再让str1与str2进行两两比较遍历操作。

 在遍历的过程之中,我们会发现当str1与str2指向的位置不相等时,难道意为着没有找到子串吗?其实不是,此时我们只能说明从绿色箭头开始,我们是不能找到想要的bbc的,但并不是整个str1字符串里是没有的。

以上没有匹配成功,那怎么办呢?我们就要退回,从绿色箭头的后一个位置(让其绿色指针自增)进行继续匹配,让str2指针也回到指向首字符的位置, 再次进行遍历比较,就找到了我们此时想要的子串。

 

此时,我们还需要考虑一个问题,那就是就拿str1指针和str2指针进行操作吗?如果进行操作,我们str1和str2需要回头进行再次操作就不知道在哪个位置了。况且我们需要将 在正确找到第一次出现str2子串的首地址 后进行返回。

所以我们

创建一个s1指针变量在str1字符串中来回移动,

创建一个s2指针变量在str2字符串中来回移动,

创建一个cp指针变量用来记录正确的第一次出现str2子串的首字符位置(绿色箭头)。

 

5.2 代码实现

有了以上逻辑分析,我们实现代码起来就很容易了。将代码整理如下:

#include<stdio.h>
#include<string.h>
char* my_strstr(const char* str1, const char* str2)
{
	char* s1 = NULL;
	char* s2 = NULL;
	char* cp = (char* )str1;

	while (*cp)
	{
		s2 = (char*)str2;
		s1 = cp;
		//*s1与*s2不为'\0',且两个指针指向的内容相等时,循环遍历
		while (*s1 && *s2 && *s1 == *s2)
		{
			s1++;
			s2++;
		}
		//说明str2字符串被查找完了,就返回匹配成功的首字符地址(cp)
		if (*s2 == '\0')
		{
			return cp;
		}
		cp++;
	}
	//没找到返回空指针
	return NULL;
}
int main()
{
	char arr1[] = "abbbcdef";
	char arr2[] = "bbc";
	char* ret = my_strstr(arr1, arr2);
	if (ret == NULL)
	{
		printf("没找到\n");
	}
	else
	{
		printf("%s", ret);
	}
	return 0;
}

 二、C库函数strtok

1.函数声明

char * strtok ( char * str, const char * sep );

2.规则

  • sep参数是个字符串,定义了用作分隔符的字符集合
  • 第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
  • strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
  • strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
  • strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
  • 如果字符串中不存在更多的标记,则返回 NULL 指针

简单理解, 就是 用作切割字符串。参数str为想要分割的字符串,sep为分割符字符串。当strtok()在参数str的字符串中发现到参数sep的分割字符时则会将该字符改为\0 字符。在第一次调用时,strtok()必须给予参数str字符串,往后的调用则将参数str置为NULL, 在下一次调用中将作为起始位置。每次调用成功则返回被分割出片段的指针,否则返回NULL指针。

3.代码使用

#include <stdio.h>
#include <string.h>
int main()
{
    char *p = "123456789@qq.com";
    const char* sep = ".@";
    char arr[30];
    char *str = NULL;
    strcpy(arr, p);//将数据拷贝一份,处理arr数组的内容
    for(str=strtok(arr, sep); str != NULL; str=strtok(NULL, sep))
    {
    printf("%s\n", str);
    }
}

 希望能够帮助到大家,有什么疑问可以私信我哦~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C库函数 ——strstr、strtok的详解 的相关文章

随机推荐

  • docker容器技术基础入门及LXC的配置

    docker容器技术基础入门及LXC的配置 1 docker简介1 2 容器与虚拟化的区别 xff1a 1 3 docker的三个基本概念1 3 1镜像1 3 2 分层储存1 3 3 容器1 3 4 仓库 2 docker产生的背景2 1
  • 简单易懂的51单片机LCD1602显示protues仿真程序

    时序图 仿真效果 include 34 AT89X51 h 34 typedef unsigned char u8 typedef unsigned int u16 define lcd1602 DB P3 sbit RS 61 P2 5
  • html5的思维导图--超详细

    下面是最近我学习总结的学习思维导图
  • 2023年天梯赛(l1 - l2全部题解)(第十二届)

    span class token macro property span class token directive hash span span class token directive keyword include span spa
  • c语言strtok函数完美实现

    看到网上好多错误的strtok实现 xff0c 也不能说错 xff0c 准确的说是没有完全的实现strtok xff0c 现自己写了下 xff0c 目前还没有找到bug xff0c 如果有不对的欢迎指出 大多数网上的strtok实现的代码跑
  • 使用vscode操作本地git

    学习目标 xff1a 使用vscode操作本地git 基础的git的命令 使用本地git进行版本穿梭 修改本地git的用户名和邮箱 git有三个状态 xff1a 工作区 暂存区 版本库 使用vscode操作本地git xff1a 1 首先
  • Linux环境下安装Docker

    1 安装Docker 1 1在linux系统中下载前置环境 1 安装wget命令 wget命令是Linux系统用于从Web下载文件的命令行工具 2 安装依赖环境 3 设置Docker镜像源 xff0c 因为默认的服务器很慢所以我选择国内镜像
  • VOC2007数据标签格式转COCO2017格式

    以下代码是将voc2007的数据标签格式转为coco2017数据标签格式 可直接基于voc2007的 xml所有文件进行处理 也可先转化为 txt文件路径之后再处理 此处我是直接基于 xml所有文件进行处理的 span class toke
  • SQLyog连接MYSQL时报错 Client does not support authentication protocol requested by server; consider upgra

    之前安装MYSQL8 0的时候安装的是绿色版 xff0c 在cmd中配置完所有参数之后 xff0c 在连接SQLyog的时候却报出了以下错误 翻译一下大致的意思为 xff1a 客户端不支持服务器请求的身份验证协议 xff1b 考虑升级MYS
  • 图神经网络对抗攻击的研究学习(一)

    目录 0 引入1 初窥1 1 图神经网络1 1 1 传统神经网络的不足1 1 2 图神经网络概况1 1 3 Graph Convolution Networks GCN 1 1 4 Graph Attention Networks GAT
  • 二叉树遍历方法——前、中、后序遍历(图解)

    目录 一 前序遍历 xff08 1 xff09 递归版本 xff08 2 xff09 非递归版本 二 中序遍历 xff08 1 xff09 递归版本 xff08 2 xff09 非递归版本 三 后序遍历 xff08 1 xff09 递归版本
  • VMware虚拟机安装Linux

    前言 接下来要分享一些Linux相关的内容 咱们来聊聊为啥要学Linux 首先 xff0c 运维靠这个吃饭 xff0c 测试要部署测试环境 大部分企业要用到Linux操作系统 xff0c 作为开发多少也要会是吧 所以 xff0c 他来了 一
  • MPU6050基本原理介绍及程序配置

    一 MPU6050简介 1 内部主要结构 xff1a 陀螺仪 加速度计 数字运动处理器DMP xff08 Digital Motion Processor xff09 PS MPU6050还含有第二IIC接口 xff0c 用于连接一个 第三
  • 2023年河北省天梯赛C语言 猜帽子游戏

    include lt stdio h gt int N K x int a 100 void solve int dui 61 0 int cuo 61 0 int mzuo 61 0 for int i 61 0 i lt N i 43
  • 树莓派4B环境配置

    前言 最近要用到树莓派 xff0c 荔枝整理了一份基础的树莓派4B配置总结 xff0c 有需要的大家自取 文章目录 前言 一 基础配置 1 1 烧录 1 2 进入桌面 1 3 开启SSH和VNC 二 更换国内源 三 查看python3版本并
  • Python之列表的基本操作

    目录 1 列表的创建与遍历 2 添加元素 3 删除元素 4 分片赋值 5 列表排序 完整代码 xff1a 本文的代码体为一个完整体 xff0c 即最开始的列表的创建与遍历中创建的列表 xff0c 为后续操作的主列表 如需从总体观看全部代码
  • Qt 实现简单的tcp网络通信

    文章目录 成品效果图 xff1a 代码 xff1a 工具头文件tool hUI文件代码 ui widget h 窗口头文件 widget h xff1a 窗口源文件widget cpp 相关代码说明 xff1a Qt获取本机ip Qt 打开
  • VNC可实现屏幕共享

    第一步 第二歩 第三步第四步 第五步 第六步 第七步
  • coco2017数据标签格式转到VOC2007格式

    以下代码是将coco2017数据集标签格式转到voc2007格式的代码 span class token operator span span class token operator span span class token opera
  • C库函数 ——strstr、strtok的详解

    x1f48c 内容专栏 xff1a C语言 进阶部分 x1f48c 本文概括 xff1a 理解C语言库函数strstr strtok的功能 x1f48c 本文作者 xff1a 花 碟 x1f48c 发布时间 xff1a 2023 3 14