当前位置: 首页 > news >正文

【C语言 模拟实现strncpy函数、strncat函数、strncmp函数、strstr函数】

C语言程序设计笔记---026

  • C语言之模拟实现strncpy函数、strncat函数、strncmp函数、strstr函数
    • 1、介绍strncpy函数
      • 1.1、模拟实现strncpy函数
    • 2、介绍strncat函数
      • 2.1、模拟实现strncat函数
    • 3、介绍strncmp函数
      • 3.1、模拟实现strncmp函数
    • 4、介绍strstr函数
      • 4.1、模拟实现strstr函数
    • 5、结语

C语言之模拟实现strncpy函数、strncat函数、strncmp函数、strstr函数

前言:
通过C语言字符串函数的知识,这篇将对strncpy、strncat、strncmp函数进行深入学习底层原理的知识,并模拟实现对应功能。

/知识点汇总/
长度不受限制的字符串函数:strcat,strcmp,strcpy
介绍长度受限制字符串函数:strncat,strncmp,strncpy
字符串查找函数:strstr

1、介绍strncpy函数

函数原型:char* strncpy(char* strDest, const char* strSource, size_t count);
函数功能:完成源字符串到目标字符串的拷贝,返回目标字符串的起始地址,返回值类型为char*,另外还可指定拷贝的长度
头文件:<string.h>
使用注意事项
(1)、源字符串必须以’\0’结束(因为会包括’\0’一起拷贝过去)
(2)、拷贝会将源字符串中的’\0’拷贝到目标空间
(3)、目标空间必须足够大,确保能存放源字符串
(4)、目标空间必须可变(不能是常量)
(5)、初始化为数组形式时,空间需要指明合适的大小
示例代码1如下

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = { 0 };char arr2[] = "abcdefghi";strncpy(arr1, arr2, 3);printf("%s\n", arr1);//abcchar arr1[20] = "xxxxxxxxxxxxxxx";char arr2[] = "abcdefghi";strncpy(arr1, arr2, 3);printf("%s\n", arr1);//abcxxxxxxxxxxreturn 0;
}

示例代码2如下
探讨拷贝长度的因素,当指定的拷贝长度比源字符串长度大时,自动补\0

#include <stdio.h>
#include <string.h>int main()
{char arr1[20] = "xxxxxxxxxxxx";char arr2[] = "abc";strncpy(arr1, arr2, 6);//6长度比str2长时,自动补的'\0'.printf("%s\n", arr1);//abc\0\0\0return 0;
}

1.1、模拟实现strncpy函数

#include <stdio.h>
#include <assert.h>
char* my_strncpy(char* str1, const char* str2, size_t num)
{assert(str1 && str2);char* ret = str1;while (num--){*str1++ = *str2++;}return ret;
}
int main()
{char arr1[] = "abcdef";char arr2[] = "defabc";printf("请输入拷贝的字符串长度:>");size_t len = 0;scanf("%zd", &len);printf("%s\n", my_strncpy(arr1, arr2,len));return 0;
}

解释说明
1.assert是断言,参数为指针,防止传参过来是空指针避免野指针的问题
2.用一个指针变量始终保存目标字符串的起始地址,以免目标起始地址发生改变,导致函数的返回值错误
3.num–执行的就是依次拷贝字符串的内容,直到num = 0,从而限制了拷贝个数,最后跳出while循环

2、介绍strncat函数

函数原型:char* strncat(char* strDest, const char* strSource, size_t count);
函数功能:完成源字符串到目标字符串的追加,返回目标字符串的起始地址,返回值类型为char*,另外还可指定追加的长度
头文件:<string.h>
使用注意事项
(1)、源字符串必须以’\0’结束(因为会包括’\0’一起追加过去)
(2)、追加会将源字符串中的’\0’拷贝到目标空间
(3)、目标空间必须足够大,确保能存放源字符串
(4)、目标空间必须可变(不能是常量)
(5)、初始化为数组形式时,空间需要指明合适的大小
示例代码1如下

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "abc";char arr2[] = "defghi";strncat(arr1, arr2, 3);printf("%s\n", arr1);//abcdefreturn 0;
}

示例代码2如下
探究’\0’的追加情况1

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "abc\0xxxxxxxxxxx";//字符串中本身具备'\0'时,依然以'\0'开始覆盖,最后补'\0'结束char arr2[] = "defghi";strncat(arr1, arr2, 3);printf("%s\n", arr1);//abcdef\0return 0;
}

示例代码3如下
探究’\0’的追加情况2

#include <stdio.h>
#include <string.h>
int main()
{char arr1[20] = "abc\0xxxxxxxxxxx";//字符串中本身具备'\0'时,依然以'\0'开始覆盖,最后补'\0'结束char arr2[] = "defghi";strncat(arr1, arr2, 10);//10长度比str2长时,自动在末尾补'\0'.此函数就不会对超出长度的字符进行操作了printf("%s\n", arr1);//abcdefreturn 0;
}

小结
①、目标字符串中本身具备’\0’时,依然以’\0’开始覆盖,最后补’\0’结束
②、指定长度长度比源字符串长时,自动在末尾补’\0’,且此函数就不会对超出长度的字符进行操作了

2.1、模拟实现strncat函数

#include <stdio.h>
#include <assert.h>
char* my_strncat(char* str1, const char* str2, size_t num)
{assert(str1 && str2);char* ret = str1;while (*str1 != '\0'){str1++;}//*str1--;while (num--){*str1++ = *str2++;}*str1 = '\0';return ret;
}
int main()
{char arr1[10] = "abc";char arr2[10] = "abc";printf("请输入追加的字符串长度:>");size_t len = 0;scanf("%zd", &len);printf("%s\n", my_strncat(arr1, arr2, len));return 0;
}

解释说明
1.assert是断言,参数为指针,防止传参过来是空指针避免野指针的问题
2.用一个指针变量始终保存目标字符串的起始地址,以免目标起始地址发生改变,导致函数的返回值错误
3.str1 != '\0’执行的就是指针遍历目标字符串的内容,直到目标字符串的下一个地址,从而再以num–限制追加的字符长度
4.值得注意的是
str1 = ‘\0’,最后需要置结束标志位,否则就是乱码,因为直到遇见’\0’才结束。

3、介绍strncmp函数

函数原型:int strncmp( const char *string1, const char *string2, size_t count );
函数功能:字符串大小比较,返回值类型为int,另外还可指定比较的长度
头文件:<string.h>
示例代码1如下

#include <stdio.h>
#include <string.h>
int main()
{char arr1[] = "abcdef";char arr2[] = "abcqw";int ret = strncmp(arr1, arr2, 3);printf("%d\n", ret);//0int ret2 = strncmp(arr1, arr2, 4);printf("%d\n", ret2);//-1return 0;
}

3.1、模拟实现strncmp函数

#include <stdio.h>
#include <assert.h>
int my_strncmp(const char* str1,const char* str2, size_t num)
{assert(str1 && str2);while (num && *str1 && *str2){if (*str1 > *str2){return 1;}if (*str1 < *str2){return -1;}num--;str1++;str2++;}return 0;
}
int main()
{char arr1[] = "abcdef";char arr2[] = "defabc";printf("请输入比较的字符串长度:>");size_t len = 0;scanf("%zd", &len);printf("%d\n", my_strncmp(arr1, arr2,len));return 0;
}

解释说明
1.assert是断言,参数为指针,防止传参过来是空指针避免野指针的问题
2.用一个指针变量始终保存目标字符串的起始地址,以免目标起始地址发生改变,导致函数的返回值错误
3.num && *str1 && *str2执行的就是依次比较字符串的内容,直到源字符串/目标字符串/指定字符长度 = 0结束,从而限制了比较字符个数,最后跳出while循环

4、介绍strstr函数

函数原型:const char *strstr( const char *string, const char *strCharSet );
函数功能:在字符串中找字符串(字符串中找子字符串或子段)
头文件:<string.h>
返回值:strstr会返回主字符串中子字符串第一次出现的位置,如果主字符串中没有子字符串,则返回NULL
示例代码1如下

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

4.1、模拟实现strstr函数

蛮力法,直接遍历查找

#include <stdio.h>
#include <assert.h>
const char* my_strstr(const char* str1, const char* str2)
{assert(str1 && str2);const char* cp;//记录开始匹配的位置const char* s1;//遍历str1指向的字符串const char* s2;//遍历str2指向的字符串if (*str2 == '\0')return str1;cp = str1;while (*cp){s1 = cp;s2 = str2;while (*s1 && *s2 && *s1 == *s2){s1++;s2++;}if (*s2 == '\0')return cp;cp++;}return NULL;
}
int main()
{char arr1[] = "abcdefghi";char arr2[] = "def";const char* ret = my_strstr(arr1, arr2);if (ret == NULL){printf("找不到\n");}else{printf("%s\n", ret);//defghi}return 0;
}

解释说明
1.assert是断言,参数为指针,防止传参过来是空指针避免野指针的问题
2.定义三个指针变量,cp用于标记返回的起始地址,s1和s2用于遍历str1和str2逐个比较即可,
3.*s1 && *s2 && *s1 == *s2执行的就是依次比较字符串的内容,直到子字符串与主字符串内容匹配则结束,最后跳出while循环,返回cp的地址。

5、结语

掌握模拟函数的逻辑思维尽可能考虑全面,学会利用画逻辑图分析并一步步的推理
学习函数的最实用的方式就是用自己的逻辑简单实现一些类似的功能
半亩方糖一鉴开,天光云影共徘徊。
问渠哪得清如许?为有源头活水来。–朱熹(观书有感)

相关文章:

【C语言 模拟实现strncpy函数、strncat函数、strncmp函数、strstr函数】

C语言程序设计笔记---026 C语言之模拟实现strncpy函数、strncat函数、strncmp函数、strstr函数1、介绍strncpy函数1.1、模拟实现strncpy函数 2、介绍strncat函数2.1、模拟实现strncat函数 3、介绍strncmp函数3.1、模拟实现strncmp函数 4、介绍strstr函数4.1、模拟实现strstr函数…...

Mongodb7启动报错排除解决方案

一&#xff1a; 报错信息: [rootwww log]# journalctl -xe -- Unit mongodb.service has begun starting up. /usr/local/mongodb/mongdb7/bin/mongod --help for more information 10月 03 13:47:39 www.yhchange.com systemd[1]: mongodb.service: control process exited, …...

王杰国庆作业day5

...

QT、C++实现地图导航系统(mapSystem)

文章目录 地图导航系统项目应用背景技术栈选择数据处理算法实现界面实现源码展示成果展示源码下载 &#xff08;免费&#xff09; 地图导航系统 项目应用背景 电子地图导航系统的主要目的是为用户提供精确、实时的导航和位置信息&#xff0c;以帮助他们在城市或地区内轻松找到…...

STM32 定时器介绍--通用、高级定时器

目录 高级定时器 1.功能框图 1-时钟源 2-时基单元 3-输入捕获 4-输出比较 2.输入捕获的应用 3.输出比较的应用 4.初始化结构体 1-时基初始化结构体 2-输出比较结构体 3-PWM信号 周期和占空比的计算--以通用定时器为例 4-输入捕获结构体 5-断路和死区初始化结构体…...

淘宝天猫渠道会员购是什么意思?如何开通天猫淘宝渠道会员购有什么用?

淘宝天猫渠道会员购是什么意思&#xff1f; 淘宝天猫渠道会员购与淘宝天猫粉丝福利购意思基本相同&#xff0c;都可以领取淘宝天猫大额内部隐藏优惠券、通过草柴APP开通绑定渠道会员还可以获得购物返利。 草柴APP如何绑定开通淘宝天猫渠道会员&#xff1f; 1、手机下载安装「…...

(Note)机器学习面试题

机器学习 1.两位同事从上海出发前往深圳出差&#xff0c;他们在不同时间出发&#xff0c;搭乘的交通工具也不同&#xff0c;能准确描述两者“上海到深圳”距离差别的是&#xff1a; A.欧式距离 B.余弦距离 C.曼哈顿距离 D.切比雪夫距离 S:D 1. 欧几里得距离 计算公式&#x…...

思科:iOS和iOSXe软件存在漏洞

思科警告说,有人试图利用iOS软件和iOSXe软件中的一个安全缺陷,这些缺陷可能会让一个经过认证的远程攻击者在受影响的系统上实现远程代码执行。 中严重程度的脆弱性被追踪为 CVE-2023-20109 ,并以6.6分得分。它会影响启用Gdoi或G-Ikev2协议的软件的所有版本。 国际知名白帽黑客…...

CCF CSP认证 历年题目自练Day19

题目一 试题编号&#xff1a; 201812-1 试题名称&#xff1a; 小明上学 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 512.0MB 问题描述&#xff1a; 题目背景   小明是汉东省政法大学附属中学的一名学生&#xff0c;他每天都要骑自行车往返于家和学校。为了能尽可能充…...

Java 开发环境配置

在本章节中我们将为大家介绍如何搭建Java开发环境。 目录 window系统安装java 下载JDK 配置环境变量 JAVA_HOME 设置 PATH设置 CLASSPATH 设置 测试JDK是否安装成功 Linux&#xff0c;UNIX&#xff0c;Solaris&#xff0c;FreeBSD环境变量设置 流行 Java 开发工具 使…...

[2023.09.26]: JsValue的转换体验与as关键字的浅析

昨天解决了焦点问题&#xff0c;今天就开始搬砖了。本以为可以一帆风顺&#xff0c;但是还是遇到了几个问题&#xff0c;不过还好&#xff0c;都被一一解决&#xff0c;这里我分享一下JsValue的转换体验以及关键字as的使用浅析。 场景描述 我是在什么情况下遇到JsValue的转换…...

SpringBoot Validation入参校验国际化

在 Spring Boot 中&#xff0c;可以使用 Validation 和国际化来实现对入参的校验。 常用的校验 NotNull验证字段值不能为 nullNotEmpty验证字段值不能为 null 或空字符串NotBlank验证字符串字段值不能为空、null&#xff0c;并且必须至少包含一个非空白字符Size验证字符串、…...

树莓集团涉足直播产业园区运营,成都直播产业园区再添黑马

树莓集团涉足成都直播产业园运营领域&#xff0c;这一消息引起了业界的广泛关注。在这个无限可能的直播领域中&#xff0c;树莓集团将与上市公司德商产投紧密合作&#xff0c;立志为成都直播行业的发展注入新的活力。成都天府蜂巢直播产业园推行着一系列创新的政策措施&#xf…...

中小学教师ChatGPT的23种用法

原文&#xff1a;中小学教师ChatGPT的23种用法 近日&#xff0c;ChatGPT引发舆论风暴&#xff0c;火遍全球。作为一款生成式人工智能软件&#xff0c;ChatGPT可以就任何议题生成文本&#xff0c;完成包括回答问题&#xff0c;撰写文章、论文、诗歌在内的多种工作。各界盛赞其“…...

Ubuntu性能分析-ftrace 底层驱动

1、框架介绍 ftrace内核驱动可以分为几部分:ftrace framework,RingBuffer,debugfs,Tracepoint,各种Tracer。 ftrace框架是整个ftrace功能的纽带,包括对内和的修改,Tracer的注册,RingBuffer的控制等等。 RingBuffer是静态动态ftrace的载体。 debugfs则提供了用户空间…...

网盘搜索引擎:点亮知识星空,畅享数字宝藏!

大家好&#xff01;作为一名资深的网络产品运营人员&#xff0c;我今天要向大家介绍一款让你受益匪浅的神奇工具——网盘搜索引擎&#xff01;它可以帮助你免费搜索查询各种云盘共享资源&#xff0c;包括影视作品、纪录片、小说、动漫等等。现在&#xff0c;我们急需网络流量&a…...

Mysql以key-val存储、正常存储的区别

场景 你作为一个服务端工程师&#xff0c;假设产品要求设计这么一个页面&#xff0c;页面上包含很多模块&#xff0c;每个模块都可以单独进行变更&#xff0c;有些模块是富文本。 实现方式有很多&#xff0c;我们来聊比较常用的两种&#xff0c;看看mysql的表如何设计。 第一…...

MySQL 索引优化实践(单表)

目录 一、前言二、表数据准备三、常见业务无索引查询耗时测试3.1、通过订单ID / 订单编号 查询指定订单3.2、查询订单列表 四、订单常见业务索引优化实践4.1、通过唯一索引和普通索引优化通过订单编号查询订单信息4.2、通过普通联合索引优化订单列表查询4.2.1、分析查询字段的查…...

react create-react-app v5配置 px2rem (暴露 eject方式)

环境信息&#xff1a; create-react-app v5 “react”: “^18.2.0” “postcss-plugin-px2rem”: “^0.8.1” 配置步骤&#xff1a; 我这个方式是 npm run eject 暴露 webpack配置的方法 1.安装 postcss-plugin-px2rem 和 lib-flexible cnpm install postcss-plugin-px2rem…...

AVL树的实现及原理

目录 AVL树的由来 AVL的实现原理 左单旋 右单旋 先左后右 先右后左 总结 AVL树的由来 查找&#xff0c;无论在什么情况下都与我们息息相关。在我们学习数组阶段学习到了线性查找&#xff0c;可是它的效率很低下&#xff0c;又演变出来了二分查找&#xff0c;它的效率非常…...

NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤

NestJs和Vite使用monorepo管理项目中,需要使用共享的文件夹步骤 1 首先需要将nest-cli打包的功能通过webpack接管 nest-cli.json文件内容 {"$schema": "https://json.schemastore.org/nest-cli","collection": "nestjs/schematics",…...

我用PYQT5做的第一个实用的上位机项目(三)

基本的程序框架&#xff1a; 因为自己不是专业的程序员&#xff0c;只是一个搞电气控制的“票友”&#xff0c;所以尽量减少手动输入 代码量&#xff0c;能在Qt Dsigner里面完成的组态就不要放在代码里面完成。 在框架的建设方面&#xff0c;尽量做到集中和整合&#xff0c;位…...

代谢组学分析平台(二)

GC/MS分析生物样本为何要衍生化处理&#xff1f;有哪些衍生化的方法&#xff1f; GC的流动相为气体&#xff08;通常为高纯氦&#xff09;&#xff0c;这就要求被分析物必须能够气化&#xff0c;而生物样本中很多内源性代谢物都含有极性基团&#xff0c;具有沸点高、不易气化特…...

【统计学】Top-down自上而下的角度模型召回率recall,精确率precision,特异性specificity,模型评价

最近在学 logistic regression model&#xff0c;又遇见了几个之前的老面孔。 召回率recall, 精确率precision&#xff0c;特异性spcificity&#xff0c;准确率accuracy&#xff0c;True positive rate&#xff0c;false positive rate等等名词在学习之初遇到的困难在于&#x…...

AutoDL使用tensorboard

目录 一&#xff0c;训练形成log文件 二. 切换logs目录 三&#xff0c;在AutoPanel中访问TensorBoard 一&#xff0c;训练形成log文件 例子&#xff1a; from torch.utils.tensorboard import SummaryWriter import numpy as npwriter SummaryWriter() for x in range(1, …...

代谢组学分析手段(一)

核磁共振技术&#xff08;Nuclear Magnetic Resonance, NMR&#xff09; 定义&#xff1a;指核磁矩不为零的原子核在外磁场的作用下&#xff0c;核自旋能级发生塞曼分裂&#xff0c;共振吸收某一特定频率的射频辐射的物理过程。 优点&#xff1a; &#xff08;1&#xff09;…...

网络基础入门(网络基础概念详解)

本篇文章主要是对网络初学的概念进行解释&#xff0c;可以让你对网络有一个大概整体的认知。 文章目录 一、简单认识网络 1、1 什么是网络 1、2 网络分类 二、网络模型 2、1OSI七层模型 2、1、1 简单认识协议 2、1、2 OSI七层模型解释 2、2 TCP/IP五层(或四层)模型 三、网络传…...

简化任务调度与管理:详解XXL-Job及Docker Compose安装

在现代应用程序开发中&#xff0c;任务调度和管理是至关重要的一部分。XXL-Job是一个强大的分布式任务调度平台&#xff0c;它使得任务的调度和管理变得更加轻松和高效。本文将介绍XXL-Job的基本概念&#xff0c;并详细演示如何使用Docker Compose进行快速安装和配置。 什么是X…...

QByteArray字节数组

QByteArray字节数组 文章目录 QByteArray字节数组1.1 QByteArray类基本使用说明1.2 设置数组字节大小1.3 返回数组大小1.4 将数据转为其他类型1.5 将数据转为C语言的字符指针返回1.6 数组数据追加1.7 清除数组数据为指定值1.8 数组数据插入1.9 删除指定位置指定长度的数据1.10 …...

ubuntu20.04.3中qt程序界面嵌套另一个qt界面

先上代码 #include "mainwindow.h" #include <QApplication> #include <iostream> using namespace std; #ifdef _WIN32// Windows 平台的代码 #include <windows.h> #elif __linux__// Linux 平台的代码// ...#include <X11/Xlib.h> #else…...

佛山专业网站营销/阿里大数据分析平台

领导力的36个关键 下载没有交易权 与生产线经理不同&#xff0c;您通常不以产品负责人的身份管理开发团队和利益相关者 &#xff0c;个人也不向您报告。 因此&#xff0c;您没有任何交易权 &#xff1a;您无法告诉别人该怎么做&#xff1b; 您不能为其分配任务&#xff1b; 并且…...

网站三大要素是什么意思/自助友链平台

JAVA面经复习&#xff08;十&#xff09; 面试难度:☆☆☆☆ 问&#xff1a;String s new String&#xff08;“abc”&#xff09;创建了几个对象? 答&#xff1a;2个&#xff0c;在JVM中存在着一个字符串池&#xff0c;其中保存着很多String对象&#xff0c;并且可以被共…...

dw做网站背景音乐/江门网站建设

最近在用element-ui遇到一些bug,在使用el-select时,数据量大了就页面渲染缓慢从而卡顿严重,为了解决这个问题,对element-ui进行了改造,el-select改为分页滚动加载: 如上图所示的效果,大数据时下拉可以分页滚动加载,而且可以支持原来的搜索。 1.新建一个selectSearch.v…...

网页设计毕业论文审批表/pc优化工具

百科&#xff1a;http://baike.baidu.com/link?urlatVCMfHUCkH7fdWmP41OL_kpyAmACcij4ffVTGg_mXtgoequLcIp1BwIiIJz7NyIPJhlWhvW7zs2L1HuhhDSOq <ehcache> <!--磁盘存储配置&#xff1a;用来指定缓存在磁盘上的存储位置。 可以使用JavaVM环境变量(user.home, user.di…...

南京网站网站建设学校/专业模板建站

爬虫理解 爬虫我认为其实就是把网上的数据给爬取下来&#xff0c;无外乎就是文本、图片、音频&#xff0c;这三大类&#xff0c;而爬虫种类比较多的的是文本&#xff0c;图片和音频重要的是路径。 爬虫分类 1、爬虫文本 &#xff08;1&#xff09;其中最简单的就是 同步获取&…...

洋桥网站建设/世界疫情最新数据

1. 重点关注地域&#xff08;base&#xff09; 2. 武汉&#xff0c;成都&#xff0c;西安&#xff0c;重庆, 杭州。...