1. strlen - 获取字符串长度
函数原型:
size_t strlen(const char *s);
功能: 计算字符串的长度(不包括结尾的 \0)
特点:
-
遇到
\0才停止计数 -
如果字符串没有
\0,会一直计数直到崩溃
示例:
char str[] = "Hello";
size_t len = strlen(str); // len = 5
2. strcpy - 字符串拷贝(不安全)
函数原型:
char *strcpy(char *dest, const char *src);
功能: 将 src 字符串(包括结尾的 \0)复制到 dest
特点:
-
不检查缓冲区大小,可能造成缓冲区溢出
-
如果 dest 空间不足,会覆盖后续内存,非常危险
示例:
char dest[10];
strcpy(dest, "Hello"); // 没问题
strcpy(dest, "Hello World!"); // 危险!dest只有10字节,但需要13字节
3. strncpy - 带长度限制的拷贝(有陷阱)
函数原型:
char *strncpy(char *dest, const char *src, size_t n);
功能: 最多复制 n 个字符到 dest
陷阱:
-
不会自动添加
\0:如果 src 长度 ≥ n,dest 不会以\0结尾 -
填充
\0:如果 src 长度 < n,会用\0填充剩余空间
示例:
char dest[10];
strncpy(dest, "Hello", 10); // dest = "Hello\0\0\0\0\0"
strncpy(dest, "Hello World!", 5); // dest = "Hello"(没有\0!)
dest[5] = '\0'; // 需要手动添加\0
4. strlcpy - BSD 安全拷贝(非标准C)
函数原型:
size_t strlcpy(char *dest, const char *src, size_t size);
功能: 安全地复制字符串,保证以 \0 结尾
特点:
-
复制最多 size-1 个字符
-
保证 dest 以
\0结尾(如果 size > 0) -
返回 src 的长度(用于检测截断)
-
不是标准C函数,是 BSD 扩展,Linux 需要定义
_BSD_SOURCE
示例:
char dest[10];
size_t len = strlcpy(dest, "Hello World!", sizeof(dest));
// dest = "Hello Worl"(自动添加\0)
// len = 12(原始字符串长度,可用于检测截断)
if (len >= sizeof(dest)) {
printf("字符串被截断了!\n");
}
5. memcpy - 内存拷贝
函数原型:
void *memcpy(void *dest, const void *src, size_t n);
功能: 从 src 复制 n 个字节到 dest
特点:
-
不关心内容,纯粹按字节复制
-
不处理
\0字符 -
src 和 dest 不能重叠(重叠用
memmove)
示例:
char src[] = "Hello\0World";
char dest[20];
memcpy(dest, src, 12); // 复制12字节,包括中间的\0
// dest = "Hello\0World"(\0后面内容也复制了)
对比总结
| 函数 | 安全性 | 终止符处理 | 适用场景 |
|---|---|---|---|
strcpy |
❌ 危险 | 自动添加 | 确定目标足够大时使用 |
strncpy |
⚠️ 有陷阱 | 不一定添加 | 不推荐,容易出错 |
strlcpy |
✅ 安全 | 保证添加 | 推荐(如果可用) |
memcpy |
⚠️ 需谨慎 | 不处理 | 任意内存块复制 |
strlen |
⚠️ 需谨慎 | 遇到\0停止 |
获取字符串长度 |
推荐用法
安全字符串拷贝(标准C)
char dest[10];
strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0'; // 手动添加终止符
安全字符串拷贝(有 strlcpy)
#ifdef __linux__
#define _BSD_SOURCE
#endif
#include <string.h>
char dest[10];
strlcpy(dest, src, sizeof(dest));
内存复制
// 确保不重叠
memcpy(dest, src, size);
// 可能重叠时使用
memmove(dest, src, size);
常见错误示例
// ❌ 错误1:strncpy 忘记添加\0
char buf[5];
strncpy(buf, "Hello", sizeof(buf));
printf("%s", buf); // 可能打印出"Hello"后跟垃圾数据
// ❌ 错误2:strcpy 溢出
char small[5];
strcpy(small, "Too long"); // 缓冲区溢出!
// ❌ 错误3:strlen 用于非字符串
char no_null[3] = {'a', 'b', 'c'};
size_t len = strlen(no_null); // 未定义行为,会继续读内存直到遇到\0
选择哪个函数取决于你的需求:
浙公网安备 33010602011771号