【C语言】字符串函数strlen #strcpy #strcmp #strcat #strstr及其模拟实现
在C语言中,有一种特殊的数据类型,即字符串类型。C 并没有专门定义一个字符串类型,这对我们使用字符串造成了一定的麻烦。但是,C标准库<string.h> 中定义了各种字符串函数,这对于我们来说是一件值得庆幸的事情。
本片着重讲解一些常用的字符串函数,以及它们的实现方法思路,并尝试自己独自模拟实现它们,以便于对字符串操作有更深的理解。
字符串简介
C语言中的字符串类型是以字符数组的形式表示的,即用一组字符数组来表示一个字符串,例如:
char str[10] = "hello"; // 定义一个长度为10的字符数组,初始化为"hello"
其中,char
表示字符类型,str
表示字符数组的名称,10
表示字符数组的长度,"hello"
表示初始值。
C语言中的字符串还可以使用字符串指针来表示,例如:
char *str = "hello"; // 定义一个指向字符数组的指针,指向"hello"
其中,char *
表示字符指针类型,str
表示指针变量的名称,"hello"
表示字符串常量,也就是一段字符数组的初始值。注意,使用字符串指针表示字符串时,需要保证指针指向的字符串常量是合法的,并且不能修改它的值,否则会发生未定义的行为。
头文件<string .h>
<string.h>是C语言标准库中的一个头文件,提供了一些字符串处理相关的函数和宏。
统一说明:
统一说明:
养成良好的代码习惯:
1.在实现字符串操作的时候,如果不希望字符串被改变,在函数形参前加上const,提高代码的健壮性。
2.使用指针前判断将要解引用的指针是否是空指针,assert进行断言。
对于每一个函数使用的注意事项放在每个函数模拟实现的末尾!
strlen
作用:
返回字符串中 ‘\0‘ 之前的所有字符数。
函数原型:
函数参数:
str是存放要操作的字符串的地址的指针
返回值类型:
size_t(表示无符号整型)的理解:由实际意义,返回的字符数不会是负数;并且看到 size_t的size,就可以知道此类型是表示大小,尺寸的类型。
模拟实现:
法一:计数变量法:
#include<stdio.h>int my_strlen(char*p)
{int c = 0;while(*p){c++;p++;}return c;
}
int main()
{char arr[] = "ahufkh";printf("%d",my_strlen(arr));return 0;
}
法二:
指针相减法:
#include<stdio.h>int my_strlen(char* p)
{char* start = p;while(*p){p++;}return p - start;
}
int main()
{char arr[] = "ahufkh";printf("%d",my_strlen(arr));return 0;
}
对size_t的补充:
易错点:
对于无符号整数,运算结果小于0,由于不存在符号位,所以结果会被当做很大的整数。
e.g.1
#typedef unsigned int uint int main() {uint a = 3;uint b = 6;uint c = a - b;//此时c是很大的整数}
结果为负值,c被当作很大的整数。
strcpy
作用:
将源字符串拷贝到目的地字符串。
函数原型:
函数参数:
1.char* dest即目的地字符串,const char* sou 即源字符串。
返回值类型:
返回拷贝后目的地字符串的地址。
模拟实现:
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest,const char* sou)
{char* s = dest;assert(dest && sou);while(*dest++ = *sou++){;}return s;
}
int main()
{char arr1[] = "abcdefghijk";char arr2[] = "iii";char* s = my_strcpy(arr1,arr2);printf("%s",s);return 0;
}
(记得const与assert断言)
注意:
1.sou字符串必须有 ’\0‘ 作为结尾。
2.dest字符串必须足够大,防止越界;并且可修改,不是常量字符串。
strcat
作用:
将源字符串拷贝到目的地字符串中,并且源字符串的的一个字符覆盖掉目的地字符串中的 ’\0‘ 。
函数原型:
函数参数:
1.const 修饰的源字符串和目标字符串。
返回值类型:
copy后的目标字符串的地址。
模拟实现:
#include<stdio.h>
#include<assert.h>
char* my_strcat(char* dest,const char* sou)
{char* start = dest;assert(dest && sou);while(*dest){dest++;}while(*dest++ = *sou++){;}return start;
}
int main()
{char arr[50] = "abc";char arr1[] = "defg";char* p = my_strcat(arr,arr1);printf("%s",p);return 0;
}
注意:
1.cou与dest字符串必有 '\0' 作为结束标志。
2.目标字符串必须足够大。
3.strcat的两个函数参数不能相同。(一个字符串对自己追加,那么一开始,自己的结束表示就被覆盖了,这样将造成死循环。)
strcmp
作用:
比较两个字符串的大小;
函数原型:
函数参数:
两个const 修饰的字符串
返回值类型:
整型数值——
if第一个>第二个,返回值>0;
if第一个=第二个,返回值=0;
if第一个<第二个,返回值<0。
模拟实现:
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char* str1,const char* str2)
{while(*str1 == *str2){if(*str1 == '\0'){return 0;}str1++;str2++;}return str1 -str2;
}
int main()
{char arr1[] = "abcde";char arr2[] = "abb";int ret = my_strcmp(arr1,arr2);if(ret > 0){printf("arr1 > arr2");}else if(ret == 0){printf("arr1 == arr2");}else{printf("arr1 < arr2");}return 0;
}
strstr
作用:
返回str2在str1中第一次出现的位置;若找不到,则返回NULL;字符串的比较匹配不包含 '\0' ,但是以 ' \0 ' 为结束标志。
函数原型:
函数参数:
查找的样本字符串和被查找的目标字符串。
返回值类型:
str1中str2第一次出现的位置。
模拟实现:
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* p1,const char* p2)
{assert(p1 && p2);const char* cur = p1;const char* s1 = NULL;const char* s2 = NULL;while(*cur){s1 = cur;s2 = p2;while(*s1 == *s2 && s1 && s2){s1++;s2++;}if(*s2 == '\0'){return (char*)cur;}cur++;}return NULL;
}
int main()
{char arr1[] = "abbbbbcdefg";char arr2[] = "bbc";char* p = my_strstr(arr1,arr2);printf("%s",p);return 0;
}
思路:
对于停下来的情况,有:
1.s1找到'\0'的同时s2也找到'\0',则找到;若s2没有到'\0',则没有找到;
2.s2到'\0',找到。
3.*s1 != *s2
于是,对s1中的每一个位置向后匹配s2的字符,如果有一个匹配失败,则从s1的下一个位置开始匹配。
完~
未经作者同意禁止转载
相关文章:

【C语言】字符串函数strlen #strcpy #strcmp #strcat #strstr及其模拟实现
在C语言中,有一种特殊的数据类型,即字符串类型。C 并没有专门定义一个字符串类型,这对我们使用字符串造成了一定的麻烦。但是,C标准库<string.h> 中定义了各种字符串函数,这对于我们来说是一件值得庆幸的事情。…...

递归实现组合型枚举
递归实现组合型枚举 #include<iostream> #include<vector>int n, m; std::vector<int>res; bool st[30];void Print() {for(int i0;i<res.size();i){printf("%d ",res[i]);}puts(""); }void dfs(int num) {if (res.size() m){Print(…...

SCAU:1065 数组中的指针
1065 数组中的指针 时间限制:1000MS 代码长度限制:10KB 提交次数:3436 通过次数:1692 题型: 编程题 语言: G;GCC Description 设有如下数组定义: int a[3][4]{{1,3,5,7},{9,11,13,15},{17,19,21,23}}; 计算下面各项的值(设数组a的首地址为2000&…...

找不到msvcp110.dll如何修复?分享5个亲测有效的修复方法
在计算机使用过程中,我们经常会遇到一些错误提示,其中之一就是“msvcp110.dll丢失”。这个错误通常发生在运行某些程序时,系统无法找到所需的动态链接库文件。那么,msvcp110.dll到底是什么呢?它又有什么作用࿱…...

LeetCode刷题笔记第80题:删除有序数组中的重复项 II
LeetCode刷题笔记第80题:删除有序数组中的重复项 II 题目: 删除升序数组中超过两次的元素后的数组长度 想法: 使用快慢指针的方法完成,使用快指针遍历整个数组,使用慢指针完成相同元素最多保留两个。在快指针遍历到…...

【开源存储】minio对象存储部署实践
文章目录 一、前言1、介绍说明2、部署方式3、冗余模式4、约束限制4.1、规格参数4.2、API支持a、minio不支持的Amazon S3 Bucket APIb、minio不支持的Amazon S3 Object API 二、部署说明1、软件安装2、minio单机部署3、minio分布式部署3.1、前置条件3.2、开始运行3.3、操作说明 …...

Java编程强化练习(二)
表达式计算(支持空格,连乘,连除)(选做题,不计分) 【问题描述】 从标准输入中读入一个整数算术运算表达式,如5 - 1 * 2 * 3 12 / 2 / 2 。计算表达式结果,并输出。 …...

Redis的高可用模式
1. 什么是高可用? 高可用(High Availability, HA)是指在信息技术中确保系统、服务或应用程序在绝大多数时间内都是可操作和可访问的能力。这通常涉及以下几个关键方面: 最小化停机时间: 高可用系统的目标是减少因硬件故障、系统升…...

非功能关键知识总结(一)
文章目录 一、稳定性(一)、服务级别协议1、SLA2、OLA3、UC (二)、可用性指标(三)、突发事件等级 三、质量(一)、千行代码缺陷数量(二)、软件质量模型的发展(三)、产品质量模型 四、安全(一)、网络安全 五、灾备(一)、灾备指标(二)、灾难恢复等级(三)、容灾技术分类 一、稳定性 …...

时间序列趋势检验相关检验方法:斜率法、Cox-Stuart检验、Mann-Kendall检验
文章目录 1.斜率法1.1.原理1.2.优缺点1.3.Python代码2.Cox-Stuart检验2.1.原理2.2.优缺点2.3.Python代码3.Mann-Kendall 检验3.1.原理3.1.1.假设前提3.1.2.趋势检验3.1.3.S到Z的变换原理3.1.4.Var(s)是如何得到的3.1.5.衡量趋势的指标:倾斜度...

Redis相关知识
yum安装redis 使用以下命令:直接将redis安装到Linux服务器(Xshell)中 yum -y install redis 启动redis 使用以下命令,以后台运行方式启动redis redis-server /etc/redis.conf & 操作redis 使用以下命令启动redis客户端 redis-…...

数据管理系统-week10-自由访问控制
文章目录 前言一、用户管理用户管理语句介绍二、数据库管理三、特权(重点考点)Administrative (global) privileges数据库特权表权限列权限四、角色参考文献前言 这节课主要讲了用户管理数据库的具体语句,数据库特权当中的全局特权,数据库特权,表特权与列特权的使用与注意…...

Python遥感开发之批量拼接
Python遥感开发之批量拼接 1 遥感图像无交错的批量拼接2 遥感图像有交错的批量拼接 前言:主要借助python实现遥感影像的批量拼接,遥感影像的批量拼接主要分为两种情况,一种是遥感图像无交错,另一种情况是遥感图像相互有交错。具体…...

【bat】批处理脚本大全
目录 1.概述 2.变量 3.运算符 3.2.重定向运算符 3.3.多命名运算符 3.4.管道运算符 4.命令 4.1.基本命令 4.2.参数传递 4.3.查看脚本内容 4.4.注释 4.5.日期和时间 4.6.启动脚本 4.7.调用其他bat 4.8.任务管理 4.8.1.任务列表查看 4.8.2.任务终止 4.9.文件夹 …...

java设计模式学习之【单例模式】
文章目录 引言单例模式简介定义与用途实现方式:饿汉式懒汉式 UML 使用场景优势与劣势单例模式在spring中的应用饿汉式实现懒汉式实现数据库连接示例代码地址 引言 单例模式是一种常用的设计模式,用于确保在一个程序中一个类只有一个实例,并且…...

UWB高精度定位系统项目源码
在现代社会中,精准定位技术对于各行各业都至关重要。为了满足对高精度定位的需求,超宽带(Ultra-Wideband, UWB)技术应运而生。UWB高精度定位系统以其出色的定位精度和多样化的应用领域而备受关注。本文将深入探讨UWB高精度定位系统…...

WPF Live Charts2 自学笔记
文章目录 前言实现效果微软平台的历史问题 WPF 项目搭建Nuget添加额外框架添加项目初始化livecharts配置其它LiveCharts2 案例简单案例Demo示例ViewViewModel GPU渲染 Github地址仓库 前言 LiveChart 是C# 上面很受欢迎的统计图 UI控件。最近在学WPFhalcon开发,想想…...

大小堆的实现(C语言)
目录 前言 一种完全二叉树:堆 堆的概念 堆的性质 建堆的时间复杂度 建堆的空间复杂度: 小堆的实现 必要补充 堆的初始化 堆的销毁 向上调整算法 堆的插入 向下调整算法 堆的删除 获取堆顶元素 获取堆中元素个数 堆的判空 最终代码 He…...

Linux系统之centos7编译安装Python 3.8
前言 CentOS (Community Enterprise Operating System) 是一种基于 Red Hat Enterprise Linux (RHEL) 进行源代码再编译并免费提供给用户的 Linux 操作系统。 CentOS 7 采用了最新的技术和软件包,并提供了强大的功能和稳定性。它适用于各种服务器和工作站应用场景&a…...

Lambda表达式与方法引用
作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO 联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬 引子 先来看一个案例 …...

二维数组处理(一)
输入整型二维数组a(5行5列),完成如下要求: 输出二维数组a。 将a的第2行和第4行元素对调后,形成新的二维数组a并按行输出,每个元素之间隔一个空格。(行号从0开始计算)。 用对角线(指二维数组左…...

基于JNI实现调用C++ SDK
基于JNI实现调用C SDK 背景分析解决实践 背景 上篇文章总结了几种Java项目调用C/C SDK项目方法,在逐一实践、踩坑后,最终还是敲定采用 JNI 方式进行实现。在文章开始的过程,会先大概讲讲笔者遇到的情况,因为封装方式需要根据实际…...

计算机组成原理笔记——存储器(静态RAM和动态RAM的区别,动态RAM的刷新, ROM……)
■ 随机存取存储器 ■ 1.随机存取存储器:按存储信息的原理不同分为:静态RAM和动态RAM 2.静态RAM(SRAM):用触发器工作原理存储信息,但电源掉电时,存储信息会丢失具有易失性。 3.存储器的基本单元…...

企业计算机服务器locked1勒索病毒数据恢复,locked1勒索病毒解密流程
随着计算机技术的不断发展,越来越多的企业走向数字化办公时代,计算机技术为企业的生产运营提供了有利条件,但也为企业带来了网络安全威胁。在本月,云天数据恢复中心陆续接到很多企业的求助,企业的速达办公软件遭到了lo…...

Session 与 JWT 的对决:谁是身份验证的王者? (下)
🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云…...

论文笔记:Confidential Assets
Confidential Assets 描述了一种称为“保密交易”的方案,该方案模糊了所有UTXO的金额,同时保持了不创建或销毁硬币的公共可验证性。进一步将此方案扩展到“保密资产”,一种单一的基于区块链的分类帐可以跟踪多种资产类型的方案。将保密交易扩…...

Docker下搭建MySQL主从复制
目录 主从复制简介 主从复制搭建 主从复制简介 主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;主数 据库一般是准实时的业务数据库。 主从复制的作用 做数据的热备。作为后备数据库,主数据库服务器故…...

VBA数据库解决方案第七讲:如何利用Recordset对象打开数据库的数据记录集
《VBA数据库解决方案》教程(版权10090845)是我推出的第二套教程,目前已经是第二版修订了。这套教程定位于中级,是学完字典后的另一个专题讲解。数据库是数据处理的利器,教程中详细介绍了利用ADO连接ACCDB和EXCEL的方法…...

内部培训平台的系统 PlayEdu搭建私有化内部培训平台
PlayEdu是由白书科技团队多年经营的线上教育系统,专为企业提供的全新企业培训方案 我们的目标是为更多的企业机构搭建私有化内部培训平台,以满足不断增长的培训需求 通过PlayEdu,企业可以有效地组织和管理培训资源,提供高质量的…...

Elasticsearch 相似度评分模型介绍
前言 Elasticsearch 是基于 Lucene 的世界范围内最流行的全文检索框架,其文档相似度算法包含 TF/IDF 和 BM25,从 ES 5.0开始 BM25 算法已经成为 ES 默认的相似度评分模块。 TF-IDF 与 BM25 的区别 TF-IDF 和 BM25 都是计算文本相似性的常用算法。TF-ID…...