news 2026/4/19 2:05:48

字符串与字符函数:用法与模拟实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
字符串与字符函数:用法与模拟实现

专栏: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( )为例 ):

#include<stdio.h>#include<ctype.h>intmain(){charch='a';if(islower(ch)){printf("是小写字母\n");}elseprintf("不是小写字母\n");return0;}

运行结果:

如果将字符'A'赋值给ch,则:

二.字符转换函数

tolower(int c):大写—>小写
toupper(int c):小写—>大写

例如(以toupper( )为例):

#include<stdio.h>#include<ctype.h>intmain(){charstr[]="Hello World!";inti=0;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);

规则:

  1. 统计到\0为止,不含\0
  2. 返回值是size_t(无符号),因为返回的是无符号,所以慎用减法比较

3.2三种模拟实现

3.2.1计数器法

intmy_strlen(constchar*str){intcount=0;while(*str++)count++;returncount;}

分析:使用计数器变量,每遍历一个有效字符,计数器加 1,指针后移一位,直到遇到\0停止并返回计数值。

3.2.2递归法(不创建临时变量)

intmy_strlen(constchar*str){if(*str=='\0')return0;return1+my_strlen(str+1);}

分析:不使用临时变量,递归思想:当前字符不为空则长度 + 1,指针后移继续递归,遇到\0递归返回。

3.2.3指针 - 指针法

intmy_strlen(constchar*str){constchar*end=str;while(*end)end++;returnend-str;}

分析:用两个指针,一个在开头、一个移到末尾,相减得到长度.

四.strcpy字符串拷贝

4.1函数原型

char*strcpy(char*dest,constchar*src);

规则:

  1. 源串必须含\0
  2. 会拷贝\0
  3. 目标空间必须足够大、可写

4.2实现模拟

char*my_strcpy(char*dest,constchar*src){char*start=dest;while((*dest++=*src++));returnstart;}

分析:保存目标地址,循环将源串字符逐个赋值到目标空间,包含\0,赋值完成后返回目标起始地址。

五.strcat字符串追加

5.1函数原型

char*strcat(char*dest,constchar*src);

规则:

  1. dest\0处开始追加
  2. 源串必须含\0
  3. 目标空间必须足够大

5.2实现模拟

char*my_strcat(char*dest,constchar*src){char*start=dest;while(*dest){dest++;}while((*dest++=*src++));returnstart;}

分析:先遍历找到目标串的\0位置,再从该位置开始将源串拷贝过去,实现字符串追加。

六.strcmp字符串比较

6.1函数原型

intstrcmp(constchar*str1,constchar*str2);

规则(返回值):

  1. 当 >0 时:str1 > str2
  2. 当 =0 时:相等
  3. 当 <0 时:str1 < str2

6.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个字符

与前面的strcpystrcatstrcmp相比较strncpystrncatstrncmp的优点在于它长度可控,更安全,我更推荐使用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*cp=str1;if(!*str2)return(char*)str1;while(*cp){s1=cp;s2=str2;while(*s1&&*s2&&*s1==*s2){s1++;s2++;}if(!*s2)return(char*)cp;cp++;}returnNULL;}

分析:使用暴力匹配算法,从主串每个位置开始尝试匹配子串,匹配成功返回当前位置地址,失败返回NULL

九.strtok字符串切割

9.1函数原型

char*strtok(char*str,constchar*delim);

特点:

  1. 修改原字符串
  2. 首次传字符串,后续传NULL
  3. 分隔符会被替换为\0

9.2举例

#include<stdio.h>#include<string.h>intmain(){charip[]="192.168.1.1";charbuf[100];strcpy(buf,ip);char*token=strtok(buf,".");while(token){printf("%s\n",token);token=strtok(NULL,".");}return0;}

运行结果:

分析:先将原字符串拷贝到临时数组,避免破坏原数据;首次切割传入数组,后续传入NULL继续切割,循环输出所有片段。

十.strerror /perror错误信息处理

10.1函数原型

char*strerror(interrnum);voidperror(constchar*msg);

功能(作用):用于获取库函数调用失败的错误信息。

10.2举例

#include<stdio.h>#include<errno.h>#include<string.h>intmain(){FILE*fp=fopen("noexist.txt","r");if(fp==NULL){printf("错误:%s\n",strerror(errno));//perror("错误");}return0;}

运行结果:

分析:打开不存在的文件会触发错误,全局变量errno被自动赋值,strerror将错误码转换为文字描述并打印,其中No such file or directory的意思是没有找到相关文件或记录

🎯总结

  1. 字符函数用于判断、转换,依赖<ctype.h>
  2. 字符串函数以\0作为结束标志。
  3. strlen三种实现:计数、递归、指针–指针
  4. strcpy、strcat、strcmp是基础字符串操作。
  5. n的版本(trncpy等)更安全可控。
  6. strstr用于子串查找,面试常考手写。
  7. strtok切割字符串,会修改原内容。
  8. strerror、perror用于错误码解析。

⚠️易错点

  1. strlen返回size_t (无符号),直接比较相减会出错。
  2. strcpy目标空间过小导致越界。
  3. 源字符串没有\0导致函数死循环。
  4. strcat不能自己追加自己。
  5. strcmp比较规则记反(并不是比较长度)。
  6. strtok直接切割常量字符串导致崩溃。
  7. 忘记包含头文件<string.h><ctype.h>
  8. 模拟实现时未用const 修饰源指针。

👀 关注 一路同行,从入门到大师,慢慢沉淀、稳步成长
❤️ 点赞 鼓励原创,让优质内容被更多人看见
⭐ 收藏 收好核心知识点与实战技巧,需要时随时查阅
💬 评论 分享你的疑问或踩坑经历,一起交流避坑、共同进步

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/19 2:05:21

Qt 5.12 多窗口程序保姆级教程:从登录对话框到主窗口的完整流程

Qt 5.12 多窗口程序实战&#xff1a;从登录验证到主界面切换的工程化实现 在桌面应用开发中&#xff0c;登录窗口与主窗口的切换是最经典的场景之一。想象一下&#xff0c;当你打开一个专业软件时&#xff0c;首先呈现的是需要输入账号密码的对话框&#xff0c;验证通过后才显示…

作者头像 李华
网站建设 2026/4/19 2:01:28

手把手教你Linux 打包压缩与 gcc 编译详解

引言在 Linux 系统中&#xff0c;文件打包压缩和程序编译是两项必备技能。打包压缩让你能够高效地管理和传输文件&#xff0c;而理解编译过程则帮助你深入理解程序从源代码到可执行文件的完整旅程。今天&#xff0c;我将通过详细的命令示例和底层原理讲解&#xff0c;带你掌握 …

作者头像 李华
网站建设 2026/4/19 2:00:20

3步轻松绕过iOS激活锁:让你的旧iPhone重获新生

3步轻松绕过iOS激活锁&#xff1a;让你的旧iPhone重获新生 【免费下载链接】applera1n icloud bypass for ios 15-16 项目地址: https://gitcode.com/gh_mirrors/ap/applera1n 你是否曾经遇到过这样的困境&#xff1f;从二手市场买来的iPhone&#xff0c;却因为前主人的…

作者头像 李华