字符串与字符函数:用法与模拟实现
专栏C语言文章目录一.字符分类函数ctype.h二.字符转换函数三.strlen字符串长度3.1函数原型3.2三种模拟实现3.2.1计数器法3.2.2递归法不创建临时变量3.2.3指针 - 指针法四.strcpy字符串拷贝4.1函数原型4.2实现模拟五.strcat字符串追加5.1函数原型5.2实现模拟六.strcmp字符串比较6.1函数原型6.2实现模拟七.strncpy、strncat、strncmp各函数原型八.strstr子串查找8.1函数原型8.2模拟实现暴力匹配九.strtok字符串切割9.1函数原型9.2举例十.strerror /perror错误信息处理10.1函数原型10.2举例总结⚠️易错点本文为C语言标准库核心接下来将学习字符分类、字符转换、strlen、strcpy、strcat、strcmp、strncpy、strncat、strncmp、strstr、strtok、strerror全套字符串处理函数包含使用规则、底层原理、模拟实现与高频易错点。前言在C语言开发中字符与字符串处理是最常用的基础能力。无论是数据解析、日志处理、文件操作还是业务逻辑都离不开字符串函数。为了让大家真正做到会用、懂原理、能手写、不踩坑本篇将学习ctype.h 与 string.h中最核心的库函数从用法到模拟实现全覆盖帮大家彻底掌握字符串处理。一.字符分类函数ctype.h用于判断字符类型返回非0表示真0表示假。常用函数都有如下表函数功能作用islower( )小写字母isupper( )大写字母isdigit( )十进制数字isxdigit( )十六进制数字isalpha( )字母isalnum( )字母或数字isspace( )空白字符举例 以islower( )为例 #includestdio.h#includectype.hintmain(){charcha;if(islower(ch)){printf(是小写字母\n);}elseprintf(不是小写字母\n);return0;}运行结果如果将字符A赋值给ch则二.字符转换函数tolower(int c)大写—小写toupper(int c)小写—大写例如以toupper( )为例#includestdio.h#includectype.hintmain(){charstr[]Hello World!;inti0;while(str[i]){if(islower(str[i]))str[i]toupper(str[i]);i;}printf(%s\n,str);return0;}运行结果三.strlen字符串长度3.1函数原型size_tstrlen(constchar*str);规则统计到\0为止不含\0返回值是size_t无符号因为返回的是无符号所以慎用减法比较3.2三种模拟实现3.2.1计数器法intmy_strlen(constchar*str){intcount0;while(*str)count;returncount;}分析使用计数器变量每遍历一个有效字符计数器加 1指针后移一位直到遇到\0停止并返回计数值。3.2.2递归法不创建临时变量intmy_strlen(constchar*str){if(*str\0)return0;return1my_strlen(str1);}分析不使用临时变量递归思想当前字符不为空则长度 1指针后移继续递归遇到\0递归返回。3.2.3指针 - 指针法intmy_strlen(constchar*str){constchar*endstr;while(*end)end;returnend-str;}分析用两个指针一个在开头、一个移到末尾相减得到长度.四.strcpy字符串拷贝4.1函数原型char*strcpy(char*dest,constchar*src);规则源串必须含\0会拷贝\0目标空间必须足够大、可写4.2实现模拟char*my_strcpy(char*dest,constchar*src){char*startdest;while((*dest*src));returnstart;}分析保存目标地址循环将源串字符逐个赋值到目标空间包含\0赋值完成后返回目标起始地址。五.strcat字符串追加5.1函数原型char*strcat(char*dest,constchar*src);规则从dest的\0处开始追加源串必须含\0目标空间必须足够大5.2实现模拟char*my_strcat(char*dest,constchar*src){char*startdest;while(*dest){dest;}while((*dest*src));returnstart;}分析先遍历找到目标串的\0位置再从该位置开始将源串拷贝过去实现字符串追加。六.strcmp字符串比较6.1函数原型intstrcmp(constchar*str1,constchar*str2);规则返回值当 0 时str1 str2当 0 时相等当 0 时str1 str26.2实现模拟intmy_strcmp(constchar*str1,constchar*str2){while(*str1*str2*str1*str2){str1;str2;}return*str1-*str2;}分析逐字符比较相等且未到末尾则继续遇到不同字符或结束时停止返回两字符的ASCII 差值。七.strncpy、strncat、strncmp各函数原型strncpy(dest,src,num);//最多拷贝num个字符strncat(dest,src,num);//最多追加num个字符strncmp(str1,str2,num);//最多比较前num个字符与前面的strcpy、strcat、strcmp相比较strncpy、strncat、strncmp的优点在于它长度可控更安全我更推荐使用strncpy、strncat、strncmp。八.strstr子串查找8.1函数原型char*strstr(constchar*str1,constchar*str2);功能作用在 str1 中查找 str2 第一次出现的位置。8.2模拟实现暴力匹配char*my_strstr(constchar*str1,constchar*str2){constchar*s1,*s2;constchar*cpstr1;if(!*str2)return(char*)str1;while(*cp){s1cp;s2str2;while(*s1*s2*s1*s2){s1;s2;}if(!*s2)return(char*)cp;cp;}returnNULL;}分析使用暴力匹配算法从主串每个位置开始尝试匹配子串匹配成功返回当前位置地址失败返回NULL。九.strtok字符串切割9.1函数原型char*strtok(char*str,constchar*delim);特点会修改原字符串首次传字符串后续传NULL分隔符会被替换为\09.2举例#includestdio.h#includestring.hintmain(){charip[]192.168.1.1;charbuf[100];strcpy(buf,ip);char*tokenstrtok(buf,.);while(token){printf(%s\n,token);tokenstrtok(NULL,.);}return0;}运行结果分析先将原字符串拷贝到临时数组避免破坏原数据首次切割传入数组后续传入NULL继续切割循环输出所有片段。十.strerror /perror错误信息处理10.1函数原型char*strerror(interrnum);voidperror(constchar*msg);功能作用用于获取库函数调用失败的错误信息。10.2举例#includestdio.h#includeerrno.h#includestring.hintmain(){FILE*fpfopen(noexist.txt,r);if(fpNULL){printf(错误%s\n,strerror(errno));//perror(错误);}return0;}运行结果分析打开不存在的文件会触发错误全局变量errno被自动赋值strerror将错误码转换为文字描述并打印其中No such file or directory的意思是没有找到相关文件或记录。总结字符函数用于判断、转换依赖ctype.h。字符串函数以\0作为结束标志。strlen三种实现计数、递归、指针–指针。strcpy、strcat、strcmp是基础字符串操作。带n的版本trncpy等更安全可控。strstr用于子串查找面试常考手写。strtok切割字符串会修改原内容。strerror、perror用于错误码解析。⚠️易错点strlen返回size_t (无符号)直接比较相减会出错。strcpy目标空间过小导致越界。源字符串没有\0导致函数死循环。strcat不能自己追加自己。strcmp比较规则记反并不是比较长度。strtok直接切割常量字符串导致崩溃。忘记包含头文件string.h或ctype.h。模拟实现时未用const 修饰源指针。 关注 一路同行从入门到大师慢慢沉淀、稳步成长❤️ 点赞 鼓励原创让优质内容被更多人看见⭐ 收藏 收好核心知识点与实战技巧需要时随时查阅 评论 分享你的疑问或踩坑经历一起交流避坑、共同进步