C语言---字符串函数总结

🚀write in front🚀
📝个人主页:认真写博客的夏目浅石.
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
📣系列专栏:夏目的C语言宝藏
💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊
✉️如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn
文章目录
- 前言
- 函数介绍以及模拟实现
- 1.1 strlen函数
- 1.2 strcpy函数
- 1.3 strcat函数
- 1.4 strcmp函数
- 1.5 strncpy函数
- 1.6 strncat函数
- 1.7 strncmp函数
- 1.8 strstr函数
- 1.9 strtok函数
- 1.10 strerror函数
- 1.11 memcpy函数
- 1.12 memmove函数
- 1.13 memcmp函数
- 总结
前言
函数的学习离不开这些
提示:以下是本篇文章正文内容,下面案例可供参考
函数介绍以及模拟实现
1.1 strlen函数
size_t strlen ( const char * str );
- 字符串已经
'\0'作为结束标志,strlen函数返回的是在字符串中'\0'前面出现的字符个数(不包含'\0')。 - 参数指向的字符串必须要以
'\0'结束。 - 注意函数的返回值为
size_t,是无符号的
设置为
size_t的原因介绍:
strlen是求字符串长度的,求出的长度是不可能为负数的
所以返回类型设置为size_t也是合情合理的
typedef unsigned int size_t
验证代码:
#include<stdio.h>
#include<string.h>int main()
{//数学上:3-6=-3;//实际上:size_t所以俩差值是一个很大的数 if(strlen("abc") - strlen("abcdef") > 0){printf(">\n");}else{printf("<=\n");}return 0;
}
运行图示:

strlen函数的模拟实现
方法一:遍历法
#include<stdio.h>
#include<assert.h>
int my_strlen(char* str)
{assert(str != NULL);int cnt=0;while(*str!='\0'){cnt++;str++;}return cnt;
}
int main()
{char arr[]="abcdef";int len=my_strlen(arr);printf("%d\n",len);return 0;
}
方法二:递归法
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* str)
{assert(str!=NULL);if(*str!='\0')return 1+my_strlen(str+1);else return 0;
}
int main()
{char arr[]="abcdef";int len=my_strlen(arr);printf("%d\n",len);return 0;
}
方法三:减指法
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* str)
{assert(str!=NULL);if(*str!='\0')return 1+my_strlen(str+1);else return 0;
}
int main()
{char arr[]="abcdef";int len=my_strlen(arr);printf("%d\n",len);return 0;
}
1.2 strcpy函数
char* strcpy(char * destination, const char * source );
- Copies the C string pointed by source into the array pointed by destination, including theterminating null character (and stopping at that point).
- 源字符串必须以
'\0'结束。 - 会将源字符串中的
'\0'拷贝到目标空间。 - 目标空间必须足够大,以确保能存放源字符串。
- 目标空间必须可变。
strcpy函数的模拟实现
方法一:遍历法
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* dest , const char* src)
{char *ret=dest;assert(dest&&src);while(*dest++ = *src++){;}return ret;
}int main()
{char arr[]="xxxxxxxxxx";char a[]="abcdef";my_strcpy(arr,a);printf("%s",arr);return 0;
}
方法二:遍历法
#include<stdio.h>
#include<assert.h>
void my_strcpy(const char*str,char* ptr)
{assert(str!=NULL);assert(ptr!=NULL);while(*str!='\0'){*ptr=*str;str++;ptr++;}
}
int main()
{char arr[]="xxxxxxxxxx";char a[]="abcdef";my_strcpy(arr,a);printf("%s",arr);return 0;
}
1.3 strcat函数
char * strcat ( char * destination, const char * source );
- Appends a copy of the source string to the destination string. The terminating null characterin destination is overwritten by the first character of source, and a null-character is includedat the end of the new string formed by the concatenation of both in destination.
- 源字符串必须以
'\0'结束。 - 目标空间必须有足够的大,能容纳下源字符串的内容。
- 目标空间必须可修改。
函数的使用:
#include<stdio.h>
#include<assert.h>
#include<string.h>int main()
{char arr[20]="hello ";strcat(arr,"world");printf("%s",arr); return 0;
}

strcat函数的模拟实现
#include<stdio.h>
#include<assert.h>
#include<string.h>char* my_strcat(char* dest,const char* src)
{assert(dest && src);char* start= dest;//1.寻找'\0'while(*dest){dest++;}//2.追加while(*dest++ = *src++){;}return start;
}int main()
{char arr[20]="hello ";my_strcat(arr,"world");printf("%s",arr); return 0;
}
1.4 strcmp函数
int strcmp ( const char * str1, const char * str2 );
- This function starts comparing the first character of each string. If they are equal to eachother, it continues with the following pairs until the characters differ or until a terminatingnull-character is reached.
- 第一个字符串大于第二个字符串,则返回大于0的数字
- 第一个字符串等于第二个字符串,则返回0
- 第一个字符串小于第二个字符串,则返回小于0的数字
strcmp函数的模拟实现
#include<stdio.h>
#include<string.h>
#include<assert.h>int my_strcmp(const char* str1,const char* str2)
{assert(str1 && str2);while(*str1 == *str2){if(*str1=='\0')return 0;str1++;str2++;}
// if(*str1 > *str2)
// return 1;
// else
// return -1;return *str1 - *str2;
}int main()
{char arr1[]="ab";char arr2[]="abcde";int ret=my_strcmp(arr1,arr2);printf("%d\n",ret);return 0;
}
1.5 strncpy函数
char * strncpy ( char * destination, const char * source, size_t num );
- Copies the first num characters of source to destination. If the end of the source C string(which is signaled by a null-character) is found before num characters have been copied,destination is padded with zeros until a total of num characters have been written to it.
- 拷贝
num个字符从源字符串到目标空间。 - 如果源字符串的长度小于
num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。
函数的使用:
#include<stdio.h>
#include<string.h>
#include<assert.h>int main()
{char arr1[20]="xxxxxxxxxx";strncpy(arr1,"abcdef",3);printf("%s\n",arr1);return 0;
}

1.6 strncat函数
char * strncat ( char * destination, const char * source, size_t num );
- Appends the first num characters of source to destination, plus a terminating null-character.
- If the length of the C string in source is less than num, only the content up to the terminatingnull-character is copied
函数的使用:
#include <stdio.h>
#include <string.h>
int main ()
{char str1[20];char str2[20];strcpy (str1,"To be ");strcpy (str2,"or not to be");strncat (str1, str2, 6);puts (str1);return 0;
}
1.7 strncmp函数
int strncmp ( const char * str1, const char * str2, size_t num );
函数的使用:
#include <stdio.h>
#include <string.h>
int main ()
{char str[][5] = { "R2D2" , "C3PO" , "R2A6" };int n;puts ("Looking for R2 astromech droids...");for (n=0 ; n<3 ; n++)if (strncmp (str[n],"R2xx",2) == 0){printf ("found %s\n",str[n]);}return 0;
}
1.8 strstr函数
char * strstr ( const char *str1, const char * str2);
- Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
函数的使用:
#include<stdio.h>
#include<string.h>
#include<assert.h>int main()
{char arr1[]="abbbbcdef";char arr2[]="bbcd";char* ret=strstr(arr1,arr2);if(ret==NULL){printf("找不到\n");} else{printf("%s\n",ret); }return 0;
}
模拟实现:
#include<stdio.h>
#include<string.h>
#include<assert.h>char* my_strstr(char* str1,char* str2)
{assert(str1&&str2);if(*str2=='\0'){return str1;}char* s1=str1;char* s2=str2;char* cp=str1;while(*cp){s1=cp;s2=str2;while(*s1!='\0' && *s2!='\0' && *s1==*s2){++s1;++s2;}if(*s2=='\0'){return cp;}cp++;}return NULL;
}int main()
{char arr1[]="abbbbcdef";char arr2[]="bbcd";char* ret= my_strstr(arr1,arr2);if(ret==NULL){printf("找不到\n");} else{printf("%s\n",ret); }return 0;
}
1.9 strtok函数
char * strtok ( char * str, const char * sep );
sep参数是个字符串,定义了用作分隔符的字符集合- 第一个参数指定一个字符串,它包含了
0个或者多个由sep字符串中一个或者多个分隔符分割的标记。 strtok函数找到str中的下一个标记,并将其用\0结尾,返回一个指向这个标记的指针。(注:
strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容
并且可修改。)strtok函数的第一个参数不为NULL,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。strtok函数的第一个参数为NULL,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。- 如果字符串中不存在更多的标记,则返回
NULL指针。
#include<stdio.h>
#include<string.h>int main()
{char arr[]="192#168.120.85";char* p="#.";char buf[20]={0};strcpy(buf,arr);char* ret=NULL;for(ret=strtok(buf,p);ret!=NULL;ret=strtok(NULL,p)){printf("%s\n",ret);}return 0;
}
1.10 strerror函数
char * strerror ( int errnum );
- 返回错误码,所对应的错误信息。

1.11 memcpy函数
void * memcpy ( void * destination, const void * source, size_t num );
- 函数
memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。 - 这个函数在遇到
'\0'的时候并不会停下来。 - 如果
source和destination有任何的重叠,复制的结果都是未定义的。
模拟实现:
#include<stdio.h>
#include<string.h>
#include<assert.h>void* my_memcpy(void* dest,const void* src,size_t num)
{void* ret=dest;assert(dest&&src);while(num--){*(char*)dest=*(char*)src;dest=(char*)dest+1;src=(char*)src+1;}return ret;
}int main()
{int arr1[]={1,2,3,4,5,6,7,8,9,10};int arr2[10]={0};my_memcpy(arr2,arr1+2,20);return 0;
}
1.12 memmove函数
void * memmove ( void * destination, const void * source, size_t num );
- 和
memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。 - 如果源空间和目标空间出现重叠,就得使用
memmove函数处理。
模拟实现:
#include<stdio.h>
#include<assert.h>void* my_memmove(void* dest,const void* src,size_t num)
{void* ret=dest;assert(dest&&src);if(dest<src){while(num--){*(char*)dest=*(char*)src;dest=(char*)dest+1;src=(char*)src+1;}}else{while(num--){*((char*)dest+num)=*((char*)src+num);}}return ret;
}int main()
{int arr[]={1,2,3,4,5,6,7,8,9,10};my_memmove(arr,arr+2,20);for(int i=0;i<10;i++){printf("%d ",arr[i]);}puts("");return 0;
}
1.13 memcmp函数
int memcmp ( const void * ptr1, const void * ptr2, size_t num );
- 比较从ptr1和ptr2指针开始的num个字节
- 返回值如下:

#include<stdio.h>
#include<string.h>int main()
{int arr1[]={1,2,6};int arr2[]={1,2,5};int ret=memcmp(arr1,arr2,9);printf("%d\n",ret);return 0;
}

总结
本期学习了很多字符串相关的函数,包括基本用法和模拟实现,都给大家书写了出来,希望大家可以多敲一遍,加深对于函数的印象。
我是夏目浅石,希望和你一起学习进步,刷题无数!!!希望各位大佬能一键三连支持一下博主,hhhh~我们下期见喽

如果无聊的话,就来逛逛我的博客栈吧stack-frame.cn
✨原创不易,还希望各位大佬支持一下\textcolor{blue}{原创不易,还希望各位大佬支持一下}原创不易,还希望各位大佬支持一下
👍 点赞,你的认可是我创作的动力!\textcolor{9c81c1}{点赞,你的认可是我创作的动力!}点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向!\textcolor{ed7976}{收藏,你的青睐是我努力的方向!}收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富!\textcolor{98c091}{评论,你的意见是我进步的财富!}评论,你的意见是我进步的财富!
相关文章:
C语言---字符串函数总结
🚀write in front🚀 📝个人主页:认真写博客的夏目浅石. 🎁欢迎各位→点赞👍 收藏⭐️ 留言📝 📣系列专栏:夏目的C语言宝藏 💬总结:希望你看完之…...
MySQL-表的基本操作
一、创建数据表创建数据表是指在已经创建好的数据库中建立新表。创建数据表的过程是规定数据列的属性的过程,同时也是实施数据完整性约束的过程。创建表之前应先使用语句{use 数据库名} 进入到指定的数据库,再执行表操作。创建表语法:CREATE TABLE <表…...
开篇之作—闲聊几句AUTOSAR
背景信息 步入职场已有些许年头,遇到过不少的人,经历过不算多的事情,也走过一些地方。现在坐下来想想,觉得一路走过总是行色匆匆,都来不及停下来驻足路边的风景,抑或是回头看看身后的精彩。 现在有些庆幸的是,加入了这个汽车这个行业,从事着汽车电子开发领域,也因此…...
02- 天池工业蒸汽量项目实战 (项目二)
忽略警告: warnings.filterwarnings("ignore") import warnings warnings.filterwarnings("ignore") 读取文件格式: pd.read_csv(train_data_file, sep\t) # 注意sep 是 , , 还是\ttrain_data.info() # 查看是否存在空数据及数据类型train_data.desc…...
LeetCode-111. 二叉树的最小深度
目录题目分析递归法题目来源111. 二叉树的最小深度题目分析 这道题目容易联想到104题的最大深度,把代码搬过来 class Solution {public int minDepth(TreeNode root) {return dfs(root);}public static int dfs(TreeNode root){if(root null){return 0;}int left…...
git常用命令
(一)克隆代码(clone):将远程仓库代码克隆到本地仓库 克隆远程仓库某个分支 git clone -b 远程分支名称 https://github.com/master/master.git 本地文件名称 克隆远程仓库默认分支 git clone https://github.com/mas…...
2022年12月电子学会Python等级考试试卷(一级)答案解析
青少年软件编程(Python)等级考试试卷(一级) 一、单选题(共25题,共50分) 1. 关于Python语言的注释,以下选项中描述错误的是?( ) A. Python语言有两种注释方式&…...
大数据未来会如何发展
大数据应用的重要性,自全国提出“数据中国”的概念以来,我们周围默默地在发挥作用的大数据逐渐深入人们的心中,大数据的应用也越来越广泛,具体到金融、汽车、餐饮、电信、能源、体育和娱乐等领域 为什么大数据技术那么火…...
2022黑马Redis跟学笔记.基础篇(一)
2022黑马Redis跟学笔记.基础篇 一1.Redis入门1.1.认识NoSQL1.1.1.结构化与非结构化1.1.2.关联和非关联1.1.3.查询方式1.1.4.事务1.1.5.总结1.2.认识Redis1.3.安装Redis步骤一:安装Redis依赖步骤二:上传安装包并解压步骤三:启动(1).默认启动(2…...
【Spring(十一)】万字带你深入学习面向切面编程AOP
文章目录前言AOP简介AOP入门案例AOP工作流程AOP切入点表达式AOP通知类型AOP通知获取数据总结前言 今天我们来学习AOP,在最初我们学习Spring时说过Spring的两大特征,一个是IOC,一个是AOP,我们现在要学习的就是这个AOP。 AOP简介 AOP:面向切面编程,一种编程范式&#…...
基于Java+SpringBoot+Vue+uniapp前后端分离图书阅读系统设计与实现
博主介绍:✌全网粉丝3W,全栈开发工程师,从事多年软件开发,在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建、毕业项目实战、项目定制✌ 博主作品:《微服务实战》专栏是本人的实战经验总结,《S…...
2021年新公开工业控制系统严重漏洞汇总
声明 本文是学习ITOT一体化工业信息安全态势报告(2019). 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 工业互联网安全威胁 2021年新公开工业控制系统严重漏洞 缓冲区溢出漏洞 缓冲区溢出(buffer overflow&…...
Canvas鼠标滚轮缩放以及画布拖动(图文并茂版)
Canvas鼠标滚轮缩放以及画布拖动 本文会带大家认识Canvas中常用的坐标变换方法 translate 和 scale,并结合这两个方法,实现鼠标滚轮缩放以及画布拖动功能。 Canvas的坐标变换 Canvas 绘图的缩放以及画布拖动主要通过 CanvasRenderingContext2D 提供的 …...
[ECCV 2020] FGVC via progressive multi-granularity training of jigsaw patches
Contents IntroductionProgressive Multi-Granularity (PMG) training frameworkExperimentsReferencesIntroduction 不同于显式地寻找特征显著区域并抽取其特征,作者充分利用了 CNN 不同 stage 输出的特征图的语义粒度信息,并使用 Jigsaw Puzzle Generator 进行数据增强来帮…...
Python推导式
列表(list)推导式 [remove for source in xx_list]或者[remove for source in xx_list if condition] 实例: names[Bob,Mark,Mausk,Johndan,Wendy] new_names[name.upper() for name in names if len(name)<5] print(new_names)即迭代列…...
Java列表List的定查改增删操作
Java列表List的定查改增删操作定义查找遍历元素与下标互查修改增加删除java.util中提供了三种常用的集合类,列表List、集合Map和字典Set。这些集合类相较于数组有更多功能,并且都可以通过Iterator(迭代器)来访问。 在这篇博客中&…...
day03java语言特性 JDK、JRE、JVM
1、Java语言的特性 1.1、简单性在Java语言当中真正操作内存的是:JVM(Java虚拟机)所有的java程序都是运行在Java虚拟机当中的。而Java虚拟机执行过程中再去操作内存。对于C或者C来说程序员都是可以直接通过指针操作内存的。C或者C更灵活&…...
HydroD 实用教程(二)有限元模型
目 录一、前言二、模型种类三、单元类型四、FEM文件五、参考文献一、前言 SESAM (Super Element Structure Analysis Module)是由挪威船级社(DNV-GL)开发的一款有限元分析(FEA)系统,它以 GeniE、…...
Java中的Set集合
Set不能存储重复元素,元素无序(指的是不按照添加的顺序,List集合是按照添加顺序存储的)hashSet注:源码底层是hashMap实现的,因为hashMap是双列的,其中键是不能重复的,而hashSet是单列…...
【RabbitMQ五】——RabbitMQ路由模式(Routing)
RabbitMQ路由模式前言RabbitMQ模式的基本概念为什么要使用Rabbitmq 路由模式RabbitMQ路由模式组成元素路由模式完整代码Pom文件引入RabbtiMQ依赖RabbitMQ工具类生产者消费者1消费者2运行结果截图前言 通过本篇博客能够简单使用RabbitMQ的路由模式。 本篇博客主要是博主通过官网…...
挑战杯推荐项目
“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 - 个性化梦境…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
