【C语言】strstr函数的使用和模拟

前言

今天给大家带来一个字符串函数,strstr()的使用介绍和模拟实现。

模拟实现这个函数,可以帮助我们更深刻地理解这个函数的功能和提高解决字符串相关问题的能力,有兴趣的话就请往下看吧。

strstr函数介绍

函数功能:

strstr函数的功能是在字符串中找另一个字符串有无出现,或者说就是找一个子字符串。如果能找到,就返回第一次出现的地址,如果找不到就返回空指针。

函数原型:

const char* strstr(const char* str1,const char* str2);或char* strtstr(char* str1,const char* str2);

可以看到,我们从函数外部接收两个字符指针,它们各自指向一个字符串的首元素地址,一个字符串是被寻找的字符串,另一个就是要找的子字符串。两个字符指针都用const修饰,因为我们不期望在这个函数中去修改字符串的内容。返回的是一个字符指针,也就是第一次出现的地址或者空指针,同样可以用const进行修饰。

需要的头文件:
#include<string.h>

函数使用:

现在,我们写个代码来看一下这个函数具体是如何使用的:

#include<stdio.h>
#include<string.h>
int main()
{char arr[] = "abcdefabcdef";char* p = "efab";char* ret = strstr(arr, p);//创建一个指针接收第一次出现的地址或空指针printf("%s\n", ret);//打印看看结果return 0;
}

在字符串“abcdefabcdef”中寻找“efab”是否出现过,很明显是出现过的,所以这时我们应该返回其第一次出现的位置,也就是字符'e'的位置。当我们用printf("%s\n", ret);将其打印,应该得到的就是“efabcdef”,因为打印会到‘\0’才停下。

vs运行效果:

可以看到,确实是这个效果。那么strstr的使用大致就是这样。

strstr函数的模拟实现

那么,现在我们能否自己写出一个函数来模拟实现库函数strstr的功能呢?当然是可以的,不过要注意将问题分析全面。

分析:

不妨就将我们自己写的strstr函数命名为my_strstr,我们可以先根据strstr的原型,模拟写出my_strstr的原型: 

const char* my_strstr(const char* str1,const char* str2)
{//
}

在上面使用strstr的代码中我们可以看到函数调用部分为char* ret = strstr(arr, p);所以由此我们可以看出应该怎么写相应的my_strstr的原型。

参数部分,因为我们要接受两个字符串,在前者中找后者,因为不期望这两个固定的字符串被修改,所以可以用const进行修饰,而返回值就是如果找到后的第一次出现的地址,也可以用const进行修饰。 

接下来,在开始找之前,我们应该再创建两个字符指针变量并分别用str1和str2对其赋值,也就是复制一对str1、str2,为什么这么做呢?因为当我们移动str1与str2,遇到匹配失败,需要让str2回到起点,str1回到某个位置时,我们已经找不到原来str1和str2指向的位置了,所以我们需要让str1与str2始终指向原本的位置,去移动复制的str1和str2。(等往下说,看到str2回到起点和str1回到某个位置的情况时,可能会更好理解)

假设此时我们的str1和s1指向“abcdefabcdef”(末尾有个隐藏的'\0'),str2和s2指向“cdef”(末尾有个隐藏的),以下是我们这个函数大致的实现逻辑:

首先我们得在str1(简约说法)中找到‘c’,因为如果连‘c’都找不到,那就是直接找不到了。找到‘c’之后就让s1和s2继续往后走进行匹配。

因为s1和s2在这个过程中会向后走,所以当我们最初在s1指向字符串中成功找到‘c’的时候要做一件事情,把当前str1中'c'的位置记录下来,因为这说明从这里开始向后是有可能匹配成功的(也就是说这可能就是我们最终要返回的值),而如果不记录下来最后我们找不回来这个位置。所以我们可以创建一个指针cur进行记录。

然后,假设确实能顺利在str1中找到str2,我们在s1和s2不断向后走的过程中,s2就会遇到‘\0’,这时就意味着匹配成功,我们只需将cur(子字符串第一次出现地址)返回就行了。

复杂情况:

但是往往情况没有那么顺利,我们需要探讨非一次匹配成功的情况,让我们的代码能够应对。

很有可能出现也比较难理解的就是多次匹配的情况

多次匹配是什么意思呢?

现在来举个例子,假设现在我们被找的字符串变为“abbbcdef”(末尾隐藏‘\0’),要找的子字符串变为“bbc”(末尾隐藏‘\0’),那么就会在s2走到‘c’的时候遇到s1不为‘c’的情况,这一次的匹配就失败了。

但是,这时的匹配失败并不代表就是在s1中找不到s2(可以看出来是找得到的),所以我们不能在一次匹配失败后就返回空指针,而是应该让cur往后走一步,让s2回到起点,s1回到cur的位置, 再重新进行匹配:

每次匹配失败我们就将cur向后移动一位,当cur遇到‘\0’的时候,就说明真的找不到了。

还有一种可能就是在某一次s1与s2往后走的时候s1提前遇到了‘\0’,这说明s1的长度已不可能出现完整的str2,可以提前返回空指针。

my_strstr完整代码参考

在分析过各种情况后,我们就能写出strstr函数的模拟实现的代码了:

vs2022运行效果:

到此,strstr函数的使用以及模拟实现的讲解就结束了,如遇到文中错误,可以向我指正。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/336230.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Hololens 2 新建自定义按钮

官方链接地址 1、创建Cube 2、添加PressableButton脚本&#xff0c;并点击AddNearin… 3、把Cube拖入到MovingButtonVisuals变量中 4、点击NearInteractionTouchable组件&#xff08;这个组件是添加和上一个脚本绑定的&#xff0c;自动添加上来的&#xff09;上的Fix… 5、…

网络之再谈体系结构

大家都知道的是网络的体系结构&#xff0c;现代软件常用的体系结构无非是TCP/IP协议栈&#xff0c;OSI因为实现复杂并且效率没有TCP/IP协议栈好&#xff0c;所以不用OSI&#xff0c;但是&#xff0c;最近在复习网络知识的时候&#xff0c;发现了一些奇怪的地方&#xff0c;那就…

ubuntu系统开启ssh密码登录

文章目录 前言 一、确认否有ssh服务 二、修改/etc/ssh/sshd_config配置文件 三、重启ssh服务 总结 前言 安装好ubuntu系统后&#xff0c;默认是无法通过密码远程shell连接的&#xff0c;需要修改配置文件。 一、确认否有ssh服务 我这边使用的是ubuntu 22.04 LTS的系统&a…

Java设计模式-活动对象与访问者

活动对象 Java设计模式中&#xff0c;活动对象是指一个对象始终处于活动的状态&#xff0c;该对象包括一个线程安全的数据结构以及一个活跃的执行线程。 如上所示&#xff0c;ActiveCreature类的构造函数初始化一个线程安全的数据结构&#xff08;阻塞队列&#xff09;、初始化…

算法练习——字符串

一确定字符串是否包含唯一字符 1.1涉及知识点 c的输入输出语法 cin>>s; cout<<"NO"; 如何定义字符串 切记&#xff1a;在[]中必须加数字——字符串最大长度&#xff0c;不然编译不通过 char s[101]; 如何获取字符串长度 char s[101];cin>>s;i…

深度学习:手撕 RNN(2)-RNN 的常见模型架构

本文首次发表于知乎&#xff0c;欢迎关注作者。 上一篇文章我们介绍了一个基本的 RNN 模块。有了 这个 RNN 模块后&#xff0c;就像搭积木一样&#xff0c;以 RNN 为基本单元&#xff0c;根据不同的任务或者需求&#xff0c;可以构建不同的模型架构。本节介绍的所有结构&#…

conda修改环境名称后,无法安装包,显示no such file

1问题描述 原本创建环境时设置的名字不太合适&#xff0c;但是因为重新创建环境很麻烦&#xff0c;安装很多包。。所以想直接对包名进行修改&#xff0c;本人采用的方式是直接找到conda环境的文件目录&#xff0c;然后修改文件名&#xff0c;简单粗暴。确实修改成功了&#xf…

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(二十三)- 微服务(3)

6. Eureka 和 Nacos 对比 共同点 : 都支持服务注册和服务拉取 都支持服务提供者心跳方式做健康检测 不同点 : 1.nacos支持服务端主动检测提供者状态&#xff0c;临时实例采用心跳模式&#xff0c;非临时实例采用主动检测模式 临时实例心跳不正常会被剔除&#xff0c;非临时实…

MySQL的安全性

给root用户设置密码 点击用户--下面三个账号双击--进行编辑 修改密码--修改完进行保存 关闭数据库后连接不上 重新编辑&#xff0c;设置密码 新建账号 填入信息--保存&#xff08;主机哪里要选择%&#xff09; 连接这个新的账号 点击连接--填写连接的名称&#xff0c;地址&…

安卓赤拳配音v1.0.2Ai配音神器+百位主播音色

Ai配音神器 本人自用版本&#xff01;超级稳定&#xff01;百位主播音色 登陆即可用 链接&#xff1a;https://pan.baidu.com/s/1WVsrYZqLaPAriHMMLMdPBg?pwdz9ru 提取码&#xff1a;z9ru

深度神经网络——什么是迁移学习?

1.概述 在练习机器学习时&#xff0c;训练模型可能需要很长时间。从头开始创建模型架构、训练模型&#xff0c;然后调整模型需要大量的时间和精力。训练机器学习模型的一种更有效的方法是使用已经定义的架构&#xff0c;可能具有已经计算出的权重。这是背后的主要思想 迁移学习…

从0开始带你成为Kafka消息中间件高手---第三讲

从0开始带你成为Kafka消息中间件高手—第三讲 实际上来说&#xff0c;每次leader接收到一条消息&#xff0c;都会更新自己的LEO&#xff0c;也就是log end offset&#xff0c;把最后一位offset 1&#xff0c;这个大家都能理解吧&#xff1f;接着各个follower会从leader请求同…

Facebook:连接世界,畅游社交之旅

作为全球最大的社交平台之一&#xff0c;Facebook不仅仅是一个网站&#xff0c;更是一个连接世界的桥梁&#xff0c;让人们可以轻松地与全球各地的朋友、家人和同事保持联系&#xff0c;分享生活、交流想法&#xff0c;畅游社交的无边界之旅。本文将带领读者探索Facebook的魅力…

php TP8 阿里云短信服务SDKV 2.0(跳大坑)

安装&#xff1a;composer require alibabacloud/dysmsapi-20170525 2.0.24 官方文档&#xff1a;短信服务_SDK中心-阿里云OpenAPI开发者门户 (aliyun.com) 特别注意&#xff1a;传入参数获得值形式 这样也不行 $sendSmsRequest new SendSmsRequest($addData); 还有一个大坑…

RFM模型-分析母婴类产品

1&#xff0c;场景描述 假设我们是某电商平台的数据分析师&#xff0c;负责分析母婴产品线的用户数据。母婴产品的购买行为具有一定的周期性和生命周期特征&#xff0c;如用户在不同怀孕阶段的需求不同&#xff0c;以及宝宝出生后的不同成长阶段需要不同的产品。 2&#xff0…

TCP/IP协议族

基于这张图片的一篇blog TCP/IP模型通常被分为四个层次&#xff1a;应用层、传输层、网络层和网络接口层。在这个模型中&#xff0c;不同的网络协议负责完成不同的任务&#xff0c;以确保数据可以在网络中高效、可靠地传输。以下是对这张图中每个协议的解释&#xff1a; 应用层…

【Linux】Socket中的心跳机制(心跳包)

Socket中的心跳机制(心跳包) 1. 什么是心跳机制&#xff1f;(心跳包) 在客户端和服务端长时间没有相互发送数据的情况下&#xff0c;我们需要一种机制来判断连接是否依然存在。直接发送任何数据包可以实现这一点&#xff0c;但为了效率和简洁&#xff0c;通常发送一个空包&am…

FPGA——eMMC验证

一.FPGA基础 1.FPGA烧录流程 (1) 加载流文件 —— bitfile (2) 烧录文件 —— cmm 二.MMC 1.基础知识 (1)jz4740、mmc、emmc、sd之间的关系&#xff1f; jz4740——处理器 mmc——存储卡标准 emmc——mmc基础上发展的高效存储解决方案 sd—— 三.eMMC和SD case验证 1.ca…

slam14讲(第8讲、前端里程计)LK光流、直接法

直接法的引出 因为第7讲大部分都是讲特征点法&#xff0c;通过提取orb特征点和点的描述子&#xff0c;来构建两帧图像之间的特征点对应关系。这种方法会有缺点&#xff1a; 关键点和描述子提取计算耗时&#xff0c;如果相机的频率高&#xff0c;则slam算法大部分耗时被占。特…

HaloDB 的 Oracle 兼容模式

↑ 关注“少安事务所”公众号&#xff0c;欢迎⭐收藏&#xff0c;不错过精彩内容~ 前倾回顾 前面介绍了“光环”数据库的基本情况和安装办法。 哈喽&#xff0c;国产数据库&#xff01;Halo DB! 三步走&#xff0c;Halo DB 安装指引 ★ HaloDB是基于原生PG打造的新一代高性能安…