字符串和字符串函数(1)
前言:
字符串在C语言中比较特别,没有单另的字符串类型,想要初始化字符串必须用字符变量的数组初始化,但是在C语言标准库函数中提供了大量能对字符串进行修改的函数,比如说可以实现字符串的的拷贝,字符串的追加,字符串的替换等等。
接下来就一起来学习这些功能,并且能够模拟实现以下这些函数的功能。
strlen函数
介绍并且使用:

简单了来说就是可以得到字符串的长度的函数,注意事项:
1、字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包 含 '\0' )。
2、参数指向的字符串必须要以 '\0' 结束。
3、注意函数的返回值为size_t,是无符号的( 易错 )。
#include<stdio.h>
#include<stdlib.h>
int main()
{char arr[] = { "abcdefg" };printf("%u\n", strlen(arr));//因为strlen返回值是一个无符号整型,我们可以用%u打印return 0;
}
很容易计算出结果是7,也就是这个字符串中有7个字符。
模拟实现strlen函数
我们可以自己编写自己的strlen函数,只需要返回一个整型,然后即可,接下来用三种方式模拟实现strlen函数。
方法一:while循环
代码如下:
int my_strlen(char *arr)
{int num = 0;while (1){if (*arr == '\0'){break;}arr++;num++;}return num;
}
int main()
{char arr[] = { "abcdefg" };printf("%d\n",my_strlen(arr));return 0;
}
方法二:递归
int my_strlen(char* arr)
{if (*arr == '\0'){return 0;}else{return 1 + my_strlen(arr + 1);}
}
int main()
{char arr[] = { "abcdefg" };printf("%d\n",my_strlen(arr));return 0;
}
方式三:指针
//指针-指针的方式
int my_strlen(char *s)
{char *p = s;while(*p != ‘\0’ )p++;return p-s;
}
int main()
{char arr[] = { "abcdefg" };printf("%d\n",my_strlen(arr));return 0;
}
strcpy函数
介绍并使用:

可以进行字符串的拷贝。从源头拷贝到目的地。
注意事项:
1、源字符串必须以 '\0' 结束。
2、会将源字符串中的 '\0' 拷贝到目标空间。
3、目标空间必须足够大,以确保能存放源字符串。
4、目标空间必须可变。
int main()
{char arr1[] = {"abcde"};char arr2[20] = {0};strcpy(arr2,arr1);printf("%s\n", arr2);return 0;
}
模拟实现strcpy函数
这里需要强调几点:
1、由于是将一个数组的字符串传到另一个字符串中,所以这两个字符串里面应该都有位置,也就是传过去的地址不能是空值(NULL)
所以用assret断言一下,如果是空值,电脑会进行报错。
2、因为传进去的时候,也要将'\0'传进去所以当判断是'\0'的时候应该要跳出循环,在跳出之前最后将'\0'传进去。
根据注意事项,即可对strcpy函数进行模拟,返回类型为char*。代码如下:
#include<assert.h>
char* my_strcpy(char* arr2, const char* arr1)
{assert(arr1 !=NULL);assert(arr2 != NULL);char* arr = arr2;while (1){if (*arr1 == '\0'){*arr2 = *arr1;break;}*arr2 = *arr1;arr1++;arr2++;}return arr;
}
int main()
{char arr1[] = {"abcde"};char arr2[20] = {0};my_strcpy(arr2, arr1);printf("%s\n",arr2 );return 0;
}
当然这里可以对代码进行升级,升级如下:
#include<assert.h>
char* my_strcpy(char* arr2, const char* arr1)
{assert(arr1 !=NULL);assert(arr2 != NULL);char* arr = arr2;while (*arr2++ = *arr1++){;}*arr2 = *arr1;return arr;
}
int main()
{char arr1[] = {"abcde"};char arr2[20] = {0};my_strcpy(arr2, arr1);printf("%s\n",arr2 );return 0;
}
strcat函数
介绍并使用:

该函数可以对字符串进行追加(连接)
例如:
int main()
{char arr1[20] = {"abcd"};char arr2[] = {"efgh"};strcat(arr1, arr2);printf("%s\n", arr1);return 0;
}
效果如下:

注意事项:
1、源字符串必须以 '\0' 结束。
2、目标空间必须有足够的大,能容纳下源字符串的内容。
3、目标空间必须可修改。
模拟实现strcat函数
这里首先根据正常逻辑分析并my_strcat
char* my_strcat(char*arr1,const char* arr2)
{assert(arr1 != NULL);assert(arr2 != NULL);char* arr = arr1;while (1){if (*arr1 == '\0'){while (1){*arr1 = *arr2;arr1++;arr2++;if (*arr2 == 0){*arr1 = *arr2;break;}}break;}arr1++;}return arr;
}
int main()
{char arr1[20] = { "abcd" };char arr2[] = {"efgh"};//my_strcat(arr1, arr2);printf("%s\n", my_strcat(arr1, arr2));return 0;
}
可以进行一次改进:(减少if语句)
char* my_strcat(char*arr1,const char* arr2)
{assert(arr1 != NULL);assert(arr2 != NULL);char* arr = arr1;while (*arr1){arr1++;}while (1){*arr1 = *arr2;if (*arr2 == 0){*arr1 = *arr2;break;}arr1++;arr2++;}return arr;
}
int main()
{char arr1[20] = { "abcd" };char arr2[] = {"efgh"};//my_strcat(arr1, arr2);printf("%s\n", my_strcat(arr1, arr2));return 0;
}
可以进行第三次改进:
char* my_strcat(char* arr1, const char* arr2)
{assert(arr1 != NULL);assert(arr2 != NULL);char* arr = arr1;while (*arr1){arr1++;}while (*arr1++ = *arr2++)//先赋值后++{;}return arr;
}
int main()
{char arr1[20] = { "abcd" };char arr2[] = { "efgh" };//my_strcat(arr1, arr2);printf("%s\n", my_strcat(arr1, arr2));return 0;
}
strcmp函数
介绍并使用:

这个函数可以实现比较两个字符串:
比较的是两个字符串的ASCALL码值,从第一个字符开始比较,返回值是这样的:
当 str1大于str2的时候,返回>0的数
当str1小于str2的时候,返回<0的数
当str1等于str2的时候,返回 = 0的数
使用代码如下:
int main()
{char arr1[] = {"abcdf"};char arr2[] = {"abct"};if (strcmp(arr1, arr2) == 0){printf("=");}else if(strcmp(arr1, arr2)>0){printf(">");}else{printf("<");}return 0;
}
模拟实现strcmp函数
初步模拟:
int my_strcmp(const char* arr1, const char* arr2)
{assert(arr1 != NULL);assert(arr2 != NULL);while (1){if (*arr1 > *arr2){return 1;}else if(*arr2 > *arr1){return -1;}else if (*arr2 == '\0' && *arr1 == '\0'){return 0;}arr1++;arr2++;}}
int main()
{char arr1[] = {"abcdef"};char arr2[] = {"abcdfk"};int c = 0;c = my_strcmp(arr1,arr2);if (c > 0){printf(">");}else if (c < 0){printf("<");}elseprintf("=");return 0;
}
二次修改:
可以自己分析一下,while函数。
int my_strcmp(const char* src, const char* dst)
{int ret = 0;assert(src != NULL);assert(dst != NULL);while (!(ret = *(unsigned char*)src - *(unsigned char*)dst) && *dst){src++;dst++;}if (ret < 0)ret = -1;else if (ret > 0)ret = 1;return ret;
}
int main()
{char arr1[] = {"abcdef"};char arr2[] = {"abcdefo"};int c = 0;c = my_strcmp(arr1,arr2);if (c > 0){printf(">");}else if (c < 0){printf("<");}elseprintf("=");return 0;
}
相关文章:
字符串和字符串函数(1)
前言: 字符串在C语言中比较特别,没有单另的字符串类型,想要初始化字符串必须用字符变量的数组初始化,但是在C语言标准库函数中提供了大量能对字符串进行修改的函数,比如说可以实现字符串的的拷贝,字符串的追…...
基于springboot+vue的班级综合测评管理系统
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
蓝海项目揭秘:跨境选品师的崛起与挑战
随着全球化贸易的日益深入和电子商务的蓬勃发展,跨境选品师这一新兴职业逐渐走进人们的视野。跨境选品师,顾名思义,就是专门负责为跨境电商平台挑选和推荐适合海外市场的商品的专业人士。那么,跨境选品师这一职业能否被视为一个蓝…...
酷黑简洁大气体育直播自适应模板赛事直播门户网站源码
源码名称:酷黑简洁大气体育直播自适应模板赛事直播门户网站源码 开发环境:帝国cms 7.5 安装环境:phpmysql 支持PC与手机端同步生成html(多端同步生成插件) 带软件采集,可以挂着自动采集发布,无…...
2024年电工杯高校数学建模竞赛(B题) 建模解析| 大学生平衡膳食食谱的优化设计
问题重述及方法概述 问题1:膳食食谱的营养分析评价及调整 数学方法:线性规划模型、营养素评价模型、比较分析 可视化数据图:营养素含量表、营养素摄入量对比图、营养素缺乏情况图 问题2:基于附件3的日平衡膳食食谱的优化设计 数…...
学习编程对英语要求高吗?
学习编程并不一定需要高深的英语水平。我这里有一套编程入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习编程,不妨点个关注,给个评论222,私信22,我在后台发给你。 虽然一些编程资源和文档可能…...
使用 Django 和 RabbitMQ 构建高效的消息队列系统
文章目录 RabbitMQ 简介Django 中使用 RabbitMQ总结与拓展 在现代的 Web 应用程序开发中,构建一个高效的消息队列系统变得越来越重要。使用消息队列可以帮助我们解耦系统中不同模块的任务,并提高系统的性能和可扩展性。本文将介绍如何结合 Django 和 Rab…...
Pycharm常见问题1
问题: ValueError at /user/users/ The view user.views.get_users didnt return an HttpResponse object. It returned None instead. 问题分析: 视图user.views.get_users未返回HttpResponse对象,它返回值为None。也就是说在视图文件没有…...
开发一个comfyui的自定义节点
文章目录 目标功能开发环境comfyui自定义节点的实现原理仓库地址完整代码目标功能 开发一个comfyui的自定义节点,该节点的功能是:可以对comfyui工作流中最终输出的图像添加一些自定义文案,且可以指定文案在图像上的位置、文案的字体样式、字体大小、字体颜色等。最终效果如…...
Prime算法构造最小生成树(加点法)
一、算法逻辑 想要轻松形象理解Prime的算法逻辑,视频肯定比图文好。 小编看过很多求相关的教学视频,这里选出一个我认为最好理解的这一款安利给大家。 因为他不仅讲解细致,而且还配合了动画演示,可以说把一个抽象的东西讲的非常…...
【VTKExamples::Utilities】第五期 CommandSubclass
很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例CommandSubclass,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. CommandSubclass …...
重生之 SpringBoot3 入门保姆级学习(04、 包扫描)
重生之 SpringBoot3 入门保姆级学习(04、 包扫描) 2.1 包扫描 2.1 包扫描 默认包扫描规则: SpringBootApplication 标注的就是主程序 SpringBoot 只会扫描主程序下面的包 自动的 component-scan 功能 在 SpringBootApplication 添加参数可以…...
VectorDBBench在windows的调试
VectorDBBench在windows的调试 VectorDBBench是一款向量数据库基准测试工具,支持milvus、Zilliz Cloud、Elastic Search、Qdrant Cloud、Weaviate Cloud 、 PgVector、PgVectorRS等,可以测试其QPS、时延、recall。 VectorDBBench是一款使用python编写的…...
KAN(Kolmogorov-Arnold Network)的理解 1
系列文章目录 第一部分 KAN的理解——数学背景 文章目录 系列文章目录前言KAN背后的数学原理:Kolmogorov-Arnold representation theorem 前言 这里记录我对于KAN的探索过程,每次会尝试理解解释一部分问题。欢迎大家和我一起讨论。 KAN tutorial KAN背…...
Vue 项目中使用 Element UI库(Element UI 是一套基于 Vue.js 的桌面端组件库)
1. 安装 Element UI npm install element-plusnext 2.引入 Element UI(在main.js中引入组件,注意要引入.css文件,图标也要单独引用) import { createApp } from vueimport ElementPlus from element-plusimport element-plus/dist/index.css…...
C++240527
定义自己的命名空间 my_sapce,在 my_sapce 中定义 string 类型的变量 s1,再 定义一个函数 完成 对字符串的逆置 。 #include <iostream>//导入 标准命名空间,cout 和 endl 标识符 存在于标准命名空间中 using namespace std;//定义了自…...
揭秘动态网页爬取:步骤与实战技巧
新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一、引言 二、动态网页爬取步骤 三、实战技巧分享 四、总结 一、引言 在大数据时代&#…...
Lvm逻辑卷调整容量
1、拉伸逻辑卷调整容量 [rootdesktop ~]# df ‐hT Filesystem Type Size Used Avail Use% Mounted on /dev/sda1 xfs 9.8G 3.3G 6.5G 34% / devtmpfs devtmpfs 660M 0 660M 0% /dev tmpfs tmpfs 674M 0 674M 0% /dev/shm tmpfs tmpfs 674M 8.9M 666M 2% /run tmpfs tmpfs 674M …...
CLIP源码详解:clip.py 文件
前言 这是关于 CLIP 源码中的 clip.py 文件中的代码带注释版本。 clip.py 文件的作用:封装了 clip 项目的相关 API,通过这些 API ,我们可以轻松使用 CLIP 项目预训练好的模型进行自己项目的应用。 另外不太容易懂的地方都使用了二级标题强…...
linux下重启oracle数据库步骤
Linux下重启oracle数据库步骤: 1.使用oracle用户登录数据库服务器(root登录的话进入数据库时会找不到sqlplus命令) su – oracle 2.通过数据库管理员sysdba进入oracle数据库 sqlplus / as sysdba 3.关闭数据库 shutdown immediate ࿰…...
MindSpore Transformers 训练任务快速上手
MindSpore Transformers(简称 MindFormers)是昇思 MindSpore 生态下的大模型训练套件,集成 BERT、GPT、LLaMA、Qwen 等主流 Transformer 模型,提供一键式预训练 / 微调、分布式并行、混合精度、监控可视化能力,适配昇腾…...
同事悄悄告诉我,他月薪比我高1.8万,岗位一模一样。我去问HR,HR说,薪资保密。我才明白,保密的从来不是他的,是我的
最近看到一个帖子,有人说,他在公司干了三年,一直以为自己的薪资还算正常,直到有一天,关系不错的同事喝多了,把工资条拍给他看。两个人同一天入职,同一个岗位,同一个绩效评级。差了1.…...
ubuntu 播放器 播放此文件需要H.264(high profile)解码器,但是没有安装
解决方法: sudo apt install gstreamer1.0-plugins-bad gstreamer1.0-libav...
3分钟搞定Figma中文界面:FigmaCN汉化插件完整指南
3分钟搞定Figma中文界面:FigmaCN汉化插件完整指南 【免费下载链接】figmaCN 中文 Figma 插件,设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma复杂的英文界面而烦恼吗?作为中文设计师࿰…...
G-Helper终极指南:3步释放华硕笔记本完整性能的轻量控制革命
G-Helper终极指南:3步释放华硕笔记本完整性能的轻量控制革命 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbo…...
如何告别网盘限速?9大主流平台直链解析完整指南
如何告别网盘限速?9大主流平台直链解析完整指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 /…...
DLSS Swapper完整指南:3分钟掌握游戏性能优化终极技巧
DLSS Swapper完整指南:3分钟掌握游戏性能优化终极技巧 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper DLSS Swapper是一款革命性的开源工具,专门为PC游戏玩家设计,让你能够轻松管理、…...
ncmdump终极指南:3步快速解密网易云音乐NCM格式,重获音乐掌控权
ncmdump终极指南:3步快速解密网易云音乐NCM格式,重获音乐掌控权 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 你是否曾为网易云音乐的NCM加密格式而烦恼?精心收藏的音乐只能在特定平台播放&…...
Unity场景文件本质解析:YAML序列化与Git工程化实践
1. 场景文件不是“点开就跑”的黑盒子,而是 Unity 项目的数据心脏很多人刚接触 Unity,把 .unity 场景文件当成一个“打包好的游戏画面快照”——双击就打开,拖拽就编辑,保存就生效。直到某天场景打不开、Prefab 变成粉红色、或者 …...
Go语言整洁架构:分层设计
Go语言整洁架构:分层设计 1. 分层结构 internal/domain/ # 领域实体usecase/ # 用例adapter/ # 适配器handler/ # HTTP处理2. 总结 整洁架构强调业务逻辑的独立性和依赖方向的正确性。...
