(C语言篇)处理字符串的四个基础函数
strlen
、strcpy
、strcat
、strcmp
使用以及注意事项
在C语言中,strlen
、strcpy
、strcat
、strcmp
是处理字符串的四个基础函数,都在<string.h>
头文件中声明。下面为你详细介绍它们的功能、用法和注意事项。
1. strlen
- 计算字符串长度
函数原型:
size_t strlen(const char *s);
功能:计算字符串s
的有效长度(不包含终止符'\0'
)。
示例:
#include <stdio.h>
#include <string.h>int main() {char str[] = "Hello";printf("长度: %zu\n", strlen(str)); // 输出: 5printf("sizeof: %zu\n", sizeof(str)); // 输出: 6(包含'\0')return 0;
}
注意点:
- 字符串必须以
'\0'
结尾,否则会导致越界访问。 - 返回值类型是
size_t
(无符号整数),进行减法运算时要特别注意溢出问题。
2. strcpy
- 复制字符串
函数原型:
char *strcpy(char *dest, const char *src);
功能:把src
字符串(包含'\0'
)复制到dest
。
示例:
#include <stdio.h>
#include <string.h>int main() {char src[] = "Hello";char dest[10];strcpy(dest, src);printf("复制结果: %s\n", dest); // 输出: Helloreturn 0;
}
注意点:
dest
必须有足够的空间,否则会引发缓冲区溢出。- 会覆盖
dest
原有的内容。 - 建议使用更安全的
strncpy
,但要手动添加'\0'
:strncpy(dest, src, sizeof(dest) - 1); dest[sizeof(dest) - 1] = '\0'; // 确保以'\0'结尾
3. strcat
- 连接字符串
函数原型:
char *strcat(char *dest, const char *src);
功能:将src
字符串(包含'\0'
)追加到dest
的末尾。
示例:
#include <stdio.h>
#include <string.h>int main() {char dest[20] = "Hello";char src[] = " World";strcat(dest, src);printf("连接结果: %s\n", dest); // 输出: Hello Worldreturn 0;
}
注意点:
dest
必须有足够的空间容纳src
,否则会导致缓冲区溢出。dest
必须是一个已经以'\0'
结尾的字符串。- 建议使用更安全的
strncat
:strncat(dest, src, sizeof(dest) - strlen(dest) - 1);
4. strcmp
- 比较字符串
函数原型:
int strcmp(const char *s1, const char *s2);
功能:按字典序比较s1
和s2
,返回值规则如下:
- 若
s1 < s2
,返回负数(通常是-1,但标准未明确规定具体值)。 - 若
s1 == s2
,返回0。 - 若
s1 > s2
,返回正数(通常是1,但标准未明确规定具体值)。
示例:
#include <stdio.h>
#include <string.h>int main() {char s1[] = "apple";char s2[] = "banana";if (strcmp(s1, s2) < 0) {printf("%s 在 %s 之前\n", s1, s2); // 输出: apple 在 banana 之前}return 0;
}
注意点:
- 比较的是字符的ASCII值(或当前字符集的编码值)。
- 常用于字符串排序或判断字符串是否相等(返回0表示相等)。
- 大小写会影响比较结果,例如
"Apple"
和"apple"
是不同的。
安全替代函数
为避免缓冲区溢出,建议优先使用以下更安全的函数:
原函数 | 安全替代函数 | 区别 |
---|---|---|
strcpy | strncpy | 需要手动添加'\0' |
strcat | strncat | 自动追加'\0' ,但需指定最大追加长度 |
- | snprintf | 可替代strcpy 和strcat ,更安全 |
总结
函数 | 功能 | 返回值 | 关键风险 |
---|---|---|---|
strlen(s) | 计算字符串s 的长度 | size_t 类型的长度值 | 字符串未以'\0' 结尾会导致越界 |
strcpy(dest, src) | 复制src 到dest | dest 的指针 | 可能引发缓冲区溢出 |
strcat(dest, src) | 将src 追加到dest 末尾 | dest 的指针 | 可能引发缓冲区溢出 |
strcmp(s1, s2) | 比较s1 和s2 | 整数(<0、0、>0) | - |
手动实现:
#include <stddef.h> // 提供size_t类型定义/* 计算字符串长度(不包含终止符'\0') */
size_t strlen(const char *s) {const char *p = s;while (*p != '\0') { // 遍历直到遇到字符串结束符p++;}return p - s; // 指针相减得到字符数量
}/* 复制字符串src到dest(包含终止符'\0') */
char *strcpy(char *dest, const char *src) {char *original_dest = dest; // 保存原始指针用于返回while ((*dest++ = *src++) != '\0'); // 复制每个字符直到遇到'\0'return original_dest; // 返回目标字符串起始地址
}/* 将字符串src追加到dest末尾(覆盖dest的终止符) */
char *strcat(char *dest, const char *src) {char *original_dest = dest;// 定位到dest的终止符位置while (*dest != '\0') {dest++;}// 从dest的终止符位置开始复制srcwhile ((*dest++ = *src++) != '\0');return original_dest; // 返回目标字符串起始地址
}/* 按字典序比较两个字符串 */
int strcmp(const char *s1, const char *s2) {while (*s1 == *s2) { // 比较相同位置的字符if (*s1 == '\0') { // 如果同时到达终止符,说明字符串相等return 0;}s1++;s2++;}// 返回第一个不相等字符的差值(ASCII码差值)return (unsigned char)*s1 - (unsigned char)*s2;
}
- strlen:
- 使用指针遍历字符串,直到遇到
'\0'
- 通过指针减法计算字符数量
- 返回类型为
size_t
(无符号整数)
- 使用指针遍历字符串,直到遇到
- strcpy:
- 使用后置递增运算符同时移动指针和赋值
- 循环条件包含赋值操作,自动处理终止符
'\0'
- 返回原始目标指针以便链式调用
- strcat:
- 先定位到
dest
的终止符位置 - 从终止符位置开始复制
src
内容(包含终止符) - 不检查
dest
空间是否足够,需调用者确保
- 先定位到
- strcmp:
- 逐字符比较直到发现差异或结束
- 返回值为第一个不相等字符的差值
- 使用
unsigned char
转换避免符号扩展导致的比较错误