C语言字符与字符串函数核心知识点解析
·
在C语言开发中,字符和字符串的处理是高频场景,标准库提供的相关函数能极大提升开发效率。
一、字符函数:字符属性判断与转换。
字符函数主要用于判断字符类型和实现大小写转换,核心依赖头文件<ctype.h>,函数参数均为 `int` 类型(输入字符时实际传入字符的ASCII码),返回值非0表示“满足条件”,0表示“不满足”。
1. 字符分类函数
核心作用是判断字符的属性,无需手动对比ASCII码,常用函数及定义如下:
int islower(int c):判断字符是否为小写字母(a-z)
int isupper(int c):判断字符是否为大写字母(A-Z)
int isdigit(int c):判断字符是否为十进制数字(0-9)
int isalpha(int c):判断字符是否为字母(a-z或A-Z)
int isalnum(int c):判断字符是否为字母或数字
int isspace(int c):判断字符是否为空白字符(空格、换行、制表符等)
2. 字符转换函数
专门用于字母的大小写互转,定义简洁且易用:
int toupper(int c):将大写字母转为小写,非字母返回原字符
int tolower(int c):将小写字母转为大写,非字母返回原字符
> 示例:将字符串中所有小写字母转为大写
c
#include <stdio.h>
#include <ctype.h>
int main() {
char str[] = "Test123 String!";
for (int i = 0; str[i]; i++) {
if (islower(str[i])) {
str[i] = toupper(str[i]); // 小写转大写
}
}
printf("%s", str); // 输出:TEST123 STRING!
return 0;
}
二、字符串函数:字符串核心操作
字符串函数是处理字符序列的核心工具,必须包含头文件 <string.h>,所有函数均以 `'\0'` 作为字符串结束标志,这是使用的关键前提。1. 字符串长度计算:strlen
- **函数定义**:size_t strlen(const char *str)
- 参数:指向以 `'\0'` 结尾的字符串指针
- 返回值:size_t(无符号整数),表示 `'\0'` 之前的字符个数(不含 `'\0'`)
- **关键要点**:
1. 字符串必须以 `'\0'` 结尾,否则会读取后续随机内存,结果未定义
2. 返回值为无符号数,不可直接用于减法比较(如 strlen(a)-strlen(b) 不会得到负数)
易错题:
#include <stdio.h>
#include <string.h>
int main() {
// 定义两个长度不同的字符串
char *short_str = "hello"; // 长度:5
char *long_str = "hello world"; // 长度:11
// 意图:判断short_str的长度是否小于long_str的长度
if (strlen(short_str) - strlen(long_str) < 0) {
printf("short_str 更短\n");
} else {
printf("short_str 不更短\n");
}
return 0;
}
分析:
第一步:分析输出结果
实际输出:short_str 不更短
第二步:错误原因详解
1.strlen 的返回值类型:strlen 的返回值是 size_t 类型(C 标准定义的无符号整数类型,通常等价于 unsigned int 或 unsigned long)。
2.无符号数的减法规则:两个无符号数相减,结果仍为无符号数(即使数学上是负数)。
o本例中:strlen(short_str) = 5,strlen(long_str) = 11,数学上 5 - 11 = -6。
o但无符号数没有负数,-6 会被转换为无符号数的「模值」(32 位系统下为 4294967290,64 位系统下为 18446744073709551610)。
o这个极大的正数与 0 比较时,> 0,因此条件 strlen(...) - strlen(...) < 0 为假。
2. 字符串拷贝:strcpy 与 strncpy
(1)无长度限制拷贝:strcpy
函数定义:char *strcpy(char *destination, const char *source)
- 功能:将源字符串(含 `'\0'`)完整拷贝到目标空间,返回目标字符串首地址
- 使用约束:
1. 源字符串必须以 `'\0'` 结尾
2. 目标空间需足够大(能容纳源字符串所有字符),且可修改(不可为常量字符串)
(2)指定长度拷贝:strncpy
-函数定义:`char *strncpy(char *destination, const char *source, size_t num)`
- 功能:仅拷贝源字符串的前 `num` 个字符到目标空间
-特殊处理:
1. 若源字符串长度小于 `num`,拷贝完源字符串后,目标空间剩余部分自动补 `'\0'`
2. 若源字符串长度大于等于 `num`,则不自动添加 `'\0'`,需手动处理!!!
3. 字符串拼接:strcat 与 strncat
(1)无长度限制拼接:strcat
-函数定义:char *strcat(char *destination, const char *source)
- 功能:将源字符串追加到目标字符串末尾,覆盖目标字符串的 `'\0'`(就是已目标字符串的”\0”作为拼接起点使用目标字符串必须要有”\0”),最终在新字符串末尾添加 `'\0'`,返回目标字符串首地址
-使用约束:
1. 源字符串和目标字符串均需以 `'\0'` 结尾
2. 目标空间需足够容纳拼接后的总字符数
字符串自己给自己拼接时要注意的问题,考虑strcat实现原理当字符串给自己追加时可能会出现乱码、程序崩溃或无规律的输出。
必须通过临时缓冲区中转,避免源和目的内存重叠
如:
#include <stdio.h>
#include <string.h>
int main() {
char str[20] = "abc"; // 扩大数组容量,避免拼接后溢出
char temp[20]; // 临时缓冲区,存储原字符串副本
// 步骤1:先将原字符串复制到临时缓冲区
strcpy(temp, str);
// 步骤2:用临时缓冲区的内容追加到原字符串(无内存重叠)
strcat(str, temp);
printf("拼接结果:%s\n", str); // 正确输出:abcabc
return 0;
}
(2)指定长度拼接:strncat
-函数定义:char *strncat(char *destination, const char *source, size_t num)
- 功能:追加源字符串的前 `num` 个字符到目标字符串末尾,自动添加 `'\0'`
- 优势:避免缓冲区溢出,比 `strcat` 更安全,源字符串长度小于 `num` 时,仅拷贝到源字符串的 `'\0'` 为止
4. 字符串比较:strcmp 与 strncmp
(1)全量比较:strcmp
- 函数定义:`int strcmp(const char *str1, const char *str2)`
- 功能:逐字符比较两字符串对应位置的ASCII码值,直到字符不同或遇到 `'\0'`
- 返回值:
- 大于0:str1对应字符ASCII码值大于str2
- 等于0:两字符串完全相同
- 小于0:str1对应字符ASCII码值小于str2
(2)指定长度比较:strncmp
- 函数定义:int strncmp(const char *str1, const char *str2, size_t num)
- 功能:仅比较num个字符,其余规则与 strcmp 一致
- 适用场景:只需判断字符串前缀是否相同(如判断文件后缀名)
5. 子串查找:strstr
-函数定义:`char *strstr(const char *str1, const char *str2)`
- 功能:在字符串str1中查找子串str2第一次出现的位置,匹配不含 `'\0'`
- 返回值:找到则返回子串首地址,未找到则返回 `NULL`
6. 字符串分割:strtok
-函数定义:`char *strtok(char *str, const char *sep)`
- 参数:str为待分割字符串(首次调用非NULL,后续调用为NULL);sep为分隔符集合
- 功能:将str按sep中的字符分割为多个子串,每次调用返回一个子串地址(子串末尾替换为 `'\0'`)
-关键要点:会修改原字符串,若需保留原字符串,需先拷贝临时副本
7. 错误信息获取:strerror
-函数定义:`char *strerror(int errnum)`
- 功能:将错误码(errnum)转换为对应的错误信息字符串,返回字符串地址
-使用场景:配合全局变量 `errno`(需包含 `<errno.h>`),库函数调用失败时,`errno` 存储错误码,通过 `strerror(errno)` 获取可读错误信息
三、核心使用原则
1. 所有字符串函数均依赖 `'\0'` 结束标志,手动初始化字符串需显式添加 `'\0'`(双引号声明自动包含)
2. 拷贝、拼接函数需确保目标空间足够大,优先使用带长度限制的 `strncpy`、`strncat` 避免溢出
3. 指针不可为 `NULL`,调用函数前需确保源/目标指针指向有效内存
4. 注意无符号返回值(如 `strlen`),避免直接参与负数相关的比较运算
更多推荐

所有评论(0)