C 语言字符函数与字符串函数超全解析 | 用法 + 模拟实现 + 避坑指南
本文全面解析了C语言标准库中的字符和字符串处理函数。首先介绍了字符分类和转换函数的使用方法及优势;然后重点讲解了核心字符串函数(strlen、strcpy、strcat、strcmp)的实现原理及模拟代码;接着分析了更安全的带n版本函数(strncpy等);最后介绍了其他实用函数(strstr、strtok等)和常见避坑要点。文章强调理解这些函数的底层实现有助于避免内存越界等错误,提升代码质量,建
在 C 语言开发中,字符和字符串的处理是高频操作。C 语言标准库提供了一系列字符函数和字符串函数来简化开发流程。本文将对这些函数进行全面解析,包含功能说明、使用示例、模拟实现以及避坑要点,帮助大家彻底掌握这些工具函数。
目录
一、字符分类函数
字符分类函数用于判断一个字符的类型,比如是否为数字、字母、小写字母等。这类函数的使用需要包含头文件 ctype.h。
1. 常用函数列表

2. 使用示例:小写字母转大写
#include <stdio.h>
#include <ctype.h>
int main()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
// 判断是否为小写字母
if (islower(c))
// 转大写
c = toupper(c);
putchar(c);
i++;
}
return 0;
}
二、字符转换函数
字符转换函数同样依赖 ctype.h 头文件,主要包含两个函数,用于大小写字母的互相转换。
1. 函数说明
tolower(int c):将大写字母转换为小写,非大写字母不处理toupper(int c):将小写字母转换为大写,非小写字母不处理
2. 优势
相较于手动通过加减 32 实现转换,使用函数更具可读性和可移植性。
三、核心字符串函数(用法 + 模拟实现)
这部分是字符串处理的核心,包含长度计算、拷贝、追加、比较等函数。使用这些函数需要包含头文件 string.h。
1. 长度计算:strlen
-
函数原型:
size_t strlen(const char *str) -
功能:计算字符串长度,统计
\0之前的字符个数 -
注意事项
- 字符串必须以
\0结尾,否则会出现越界访问 - 返回值
size_t是无符号整数,相减时容易出错
- 字符串必须以
-
模拟实现(三种方式)
#include <assert.h>
// 方式1:计数器法
int my_strlen(const char* str)
{
assert(str);
int count = 0;
while (*str)
{
count++;
str++;
}
return count;
}
// 方式2:递归法(无临时变量)
int my_strlen(const char* str)
{
assert(str);
if (*str == '\0')
return 0;
return 1 + my_strlen(str + 1);
}
// 方式3:指针-指针法
int my_strlen(char* s)
{
assert(s);
char* p = s;
while (*p != '\0')
p++;
return p - s;
}
2. 字符串拷贝:strcpy
-
函数原型:
char* strcpy(char *dest, const char *src) -
功能:将源字符串拷贝到目标空间,包含
\0 -
注意事项
- 源字符串必须以
\0结尾 - 目标空间需足够大且可修改
- 源字符串必须以
-
模拟实现
#include <assert.h>
char* my_strcpy(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
while ((*dest++ = *src++))
{
;
}
return ret;
}
3. 字符串追加:strcat
-
函数原型:
char* strcat(char *dest, const char *src) -
功能:将源字符串追加到目标字符串末尾
-
注意事项
- 源字符串和目标字符串都要以
\0结尾 - 目标空间需足够容纳拼接后的字符串
- 源字符串和目标字符串都要以
-
模拟实现
#include <assert.h>
char* my_strcat(char* dest, const char* src)
{
assert(dest && src);
char* ret = dest;
// 找到目标字符串的末尾
while (*dest)
{
dest++;
}
// 追加源字符串
while ((*dest++ = *src++))
{
;
}
return ret;
}
4. 字符串比较:strcmp
-
函数原型:
int strcmp(const char *str1, const char *str2) -
功能:按 ASCII 码值比较两个字符串
-
返回值规则
- 若
str1 > str2,返回大于 0 的数 - 若
str1 == str2,返回 0 - 若
str1 < str2,返回小于 0 的数
- 若
-
模拟实现
#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++;
}
return *str1 - *str2;
}
四、更安全的字符串函数(带 n 限制)
上述 strcpy、strcat、strcmp 存在越界风险,对应的带 n 版本函数可以指定操作长度,更安全。
1. strncpy
- 函数原型:
char* strncpy(char *dest, const char *src, size_t num) - 功能:最多拷贝
num个字符到目标空间 - 特点:若源字符串长度小于
num,剩余部分用\0填充
2. strncat
- 函数原型:
char* strncat(char *dest, const char *src, size_t num) - 功能:最多追加
num个字符到目标字符串末尾 - 特点:追加完成后自动添加
\0
3. strncmp
- 函数原型:
int strncmp(const char *str1, const char *str2, size_t num) - 功能:最多比较前
num个字符
五、其他实用字符串函数
1. 字符串查找:strstr
- 函数原型:
char* strstr(const char *str1, const char *str2) - 功能:在
str1中查找str2第一次出现的位置 - 返回值:找到返回对应指针,未找到返回
NULL
2. 字符串分割:strtok
-
函数原型:
char* strtok(char *str, const char *sep) -
功能:按照分隔符集合
sep分割字符串str -
使用特点
- 第一次调用传入
str,后续调用传入NULL - 函数会修改原字符串,建议使用临时拷贝
- 第一次调用传入
-
使用示例
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "192.168.6.111";
char* sep = ".";
char* str = NULL;
for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
{
printf("%s\n", str);
}
return 0;
}
3. 错误信息获取:strerror
-
函数原型:
char* strerror(int errnum) -
功能:将错误码转换为对应的错误信息字符串
-
使用:需包含
errno.h,配合全局变量errno使用 -
示例
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main()
{
FILE* pFile = fopen("unexist.ent", "r");
if (pFile == NULL)
printf("Error: %s\n", strerror(errno));
return 0;
}
六、避坑指南
- strlen 返回值陷阱:
size_t是无符号数,strlen(str2)-strlen(str1)永远不会为负 - strcpy 目标空间问题:必须确保目标空间可修改且足够大,避免数组越界
- strcat 自追加问题:不能用
strcat(str, str),会覆盖\0导致死循环 - strtok 修改原字符串:如需保留原字符串,先进行拷贝
七、总结
字符函数和字符串函数是 C 语言处理文本数据的基础,掌握这些函数的用法、注意事项和底层实现,不仅能提升代码质量,还能避免常见的内存越界、逻辑错误。建议大家手动实现这些函数,加深对字符串处理逻辑的理解。
如果本篇内容对你有帮助,欢迎点赞、收藏、关注!有任何疑问,评论区留言交流~
更多推荐



所有评论(0)