字符串和字符串函数(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 ࿰…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级
在互联网的快速发展中,高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司,近期做出了一个重大技术决策:弃用长期使用的 Nginx,转而采用其内部开发…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
