字符串与内存操作
涵盖
<string.h>中的 mem* 系列(内存块操作)和 str* 系列(C 字符串操作)。
内存操作(无需空字符终止)
| 函数 | 签名 | 说明 |
|---|---|---|
memcpy | void *memcpy(void *dest, const void *src, size_t n) | 从 src 复制 n 字节到 dest(不处理重叠) |
memmove | void *memmove(void *dest, const void *src, size_t n) | 安全版,处理重叠区域 |
memset | void *memset(void *s, int c, size_t n) | 将 s 的前 n 字节设置为 (unsigned char)c |
memcmp | int memcmp(const void *s1, const void *s2, size_t n) | 逐字节比较前 n 个字节 |
memchr | void *memchr(const void *s, int c, size_t n) | 在 n 字节范围内查找字符 c 首次出现 |
关键概念:内存操作函数操作原始字节,不检查
\0。memcpy假设源和目标不重叠(可优化为 SIMD),memmove正确处理重叠。memset按字节设置,不能用于将 int 数组初始化为非零值。
字符串查询(只读)
| 函数 | 签名 | 说明 |
|---|---|---|
strlen | size_t strlen(const char *s) | 返回字符串长度(不含 \0),O(n) |
strchr | char *strchr(const char *s, int c) | 查找字符 c 首次出现 |
strrchr | char *strrchr(const char *s, int c) | 查找字符 c 末次出现 |
strstr | char *strstr(const char *haystack, const char *needle) | 查找子串首次出现 |
字符串比较
| 函数 | 签名 | 说明 |
|---|---|---|
strcmp | int strcmp(const char *s1, const char *s2) | 字典序比较完整字符串 |
strncmp | int strncmp(const char *s1, const char *s2, size_t n) | 最多比较前 n 个字符 |
返回值:<0 (s1<s2), 0 (相等), >0 (s1>s2)。
字符串复制与拼接
| 函数 | 签名 | 说明 |
|---|---|---|
strcpy | char *strcpy(char *dest, const char *src) | 复制 src 到 dest(含 \0),不检查 dest 大小 |
strncpy | char *strncpy(char *dest, const char *src, size_t n) | 最多复制 n 字符;若 src 长度 >= n 则不会追加 \0 |
strcat | char *strcat(char *dest, const char *src) | 拼接 src 到 dest 末尾,不检查 dest 大小 |
strncat | char *strncat(char *dest, const char *src, size_t n) | 最多拼接 n 字符,始终追加 \0 |
关键概念:
strcpy和strcat是缓冲区溢出漏洞的主要来源。strncpy设计为填充定长字段,非安全字符串复制。strncat行为更合理。实际项目推荐使用snprintf。
字符串分割
| 函数 | 签名 | 说明 |
|---|---|---|
strtok | char *strtok(char *str, const char *delim) | 按分隔符分割,首次传 str,后续传 NULL;不可重入,修改原字符串 |
strtok使用静态缓冲区,多线程不安全。POSIX 提供线程安全版本strtok_r。