C语言<string.h>中字符串函数全解析
在 C 语言中,字符串处理是程序开发中的重要组成部分。C 标准库 <string.h>
提供了一系列函数用于操作字符数组(即字符串)。这些函数以 str
开头,功能强大、使用广泛,掌握它们对编写高效、安全的字符串处理代码至关重要。下面将详细介绍所有常用的字符串处理函数,包括其 函数原型、参数说明、返回值含义 以及 完整示例代码。
📢 如果你正在学习 C 语言或准备面试,请收藏此篇,作为你的字符串函数速查手册!
文章目录
- C语言<string.h>中字符串函数全解析
-
- 🔹1. `strcpy()` —— 字符串拷贝
- 🔹2. `strncpy()` —— 指定长度的字符串拷贝
- 🔹3. `strcat()` —— 字符串拼接
- 🔹4. `strncat()` —— 指定长度的字符串拼接
- 🔹5. `strcmp()` —— 字符串比较
- 🔹6. `strncmp()` —— 指定长度的字符串比较
- 🔹7. `strlen()` —— 获取字符串长度
- 🔹8. `strchr()` —— 查找字符首次出现位置
- 🔹9. `strrchr()` —— 查找字符最后一次出现位置
- 🔹10. `strstr()` —— 查找子字符串首次出现位置
- 🔹11. `strspn()` —— 计算前缀匹配长度
- 🔹12. `strcspn()` —— 计算前缀不含某字符集的长度
- 🔹13. `strpbrk()` —— 查找第一个出现在指定字符集中的字符
- 🔹14. `strdup()` —— 字符串复制(非标准但常用)
- 🔹15. `strndup()` —— 指定长度的字符串复制(GNU扩展)
- 🔹16. `strerror()` —— 根据错误码获取描述信息
- 🔹17. `strtok()` / `strtok_r()` —— 字符串分割
- 🔹18. `strcoll()` —— 按照当前区域设置比较字符串
- 🔹19. `strxfrm()` —— 将字符串转换为可排序形式
- ✅ 总结表格(含参数说明)
🔹1. strcpy()
—— 字符串拷贝
函数原型:
char *strcpy(char *dest, const char *src);
参数说明:
dest
:指向目标字符数组的指针,用于存储复制后的字符串。src
:指向源字符串的指针,该字符串将被复制到dest
中。
返回值:
返回指向 dest
的指针。
示例:
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello World";
char dest[50];
strcpy(dest, src);
printf("Copied string: %s\n", dest);
return 0;
}
🔹2. strncpy()
—— 指定长度的字符串拷贝
函数原型:
char *strncpy(char *dest, const char *src, size_t n);
参数说明:
dest
:目标缓冲区。src
:源字符串。n
:最多拷贝的字符数。
返回值:
返回指向 dest
的指针。
示例:
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "abcdefg";
char dest[10];
strncpy(dest, src, 3);
dest[3] = '\0'; // 手动补结束符
printf("Copied substring: %s\n", dest);
return 0;
}
🔹3. strcat()
—— 字符串拼接
函数原型:
char *strcat(char *dest, const char *src);
参数说明:
dest
:原字符串,必须有足够空间容纳结果。src
:要拼接到dest
后面的字符串。
返回值:
返回指向 dest
的指针。
示例:
#include <stdio.h>
#include <string.h>
int main() {
char dest[50] = "Hello ";
strcat(dest, "World");
printf("Concatenated string: %s\n", dest);
return 0;
}
🔹4. strncat()
—— 指定长度的字符串拼接
函数原型:
char *strncat(char *dest, const char *src, size_t n);
参数说明:
dest
:原字符串。src
:要拼接的字符串。n
:最多拼接的字符数。
返回值:
返回指向 dest
的指针。
示例:
#include <stdio.h>
#include <string.h>
int main() {
char dest[50] = "Hello ";
strncat(dest, "World!", 3);
printf("Concatenated substring: %s\n", dest);
return 0;
}
🔹5. strcmp()
—— 字符串比较
函数原型:
int strcmp(const char *s1, const char *s2);
参数说明:
s1
:第一个待比较的字符串。s2
:第二个待比较的字符串。
返回值:
- 小于 0:
s1 < s2
- 等于 0:
s1 == s2
- 大于 0:
s1 > s2
示例:
#include <stdio.h>
#include <string.h>
int main() {
if (strcmp("apple", "banana") < 0) {
printf("apple comes before banana\n");
} else {
printf("apple does not come before banana\n");
}
return 0;
}
🔹6. strncmp()
—— 指定长度的字符串比较
函数原型:
int strncmp(const char *s1, const char *s2, size_t n);
参数说明:
s1
:第一个字符串。s2
:第二个字符串。n
:最多比较的字符数。
返回值:
同上。
示例:
#include <stdio.h>
#include <string.h>
int main() {
if (strncmp("hello world", "hello there", 5) == 0) {
printf("First 5 characters are equal.\n");
} else {
printf("First 5 characters are different.\n");
}
return 0;
}
🔹7. strlen()
—— 获取字符串长度
函数原型:
size_t strlen(const char *s);
参数说明:
s
:要计算长度的字符串。
返回值:
返回字符串 s
的长度(不包括终止符 \0
)。
示例:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello";
printf("Length of '%s': %zu\n", str, strlen(str));
return 0;
}
🔹8. strchr()
—— 查找字符首次出现位置
函数原型:
char *strchr(const char *s, int c);
参数说明:
s
:要查找的字符串。c
:要查找的字符(会被隐式转换为char
类型)。
返回值:
返回指向第一次出现的位置的指针;若未找到,则返回 NULL
。
示例:
#include <stdio.h>
#include <string.h>
int main() {
const char *str = "abcdefg";
char *p = strchr(str, 'd');
if (p) {
printf("Found 'd' at position: %ld\n", p - str);
} else {
printf("'d' not found\n");
}
return 0;
}
🔹9. strrchr()
—— 查找字符最后一次出现位置
函数原型:
char *strrchr(const char *s, int c);
参数说明:
s
:要查找的字符串。c
:要查找的字符。
返回值:
返回最后一次出现的指针;未找到则返回 NULL
。
示例:
#include <stdio.h>
#include <string.h>
int main() {
const char *str = "abracadabra";
char *p = strrchr(str, 'a');
if (p) {
printf("Last 'a' at index: %ld\n", p - str);
} else {
printf("'a' not found\n");
}
return 0;
}
🔹10. strstr()
—— 查找子字符串首次出现位置
函数原型:
char *strstr(const char *haystack, const char *needle);
参数说明:
haystack
:主字符串。needle
:要查找的子字符串。
返回值:
返回匹配子串起始位置的指针;未找到则返回 NULL
。
示例:
#include <stdio.h>
#include <string.h>
int main() {
const char *text = "Hello World";
const char *pattern = "World";
char *p = strstr(text, pattern);
if (p) {
printf("Found '%s' at index: %ld\n", pattern, p - text);
} else {
printf("'%s' not found\n", pattern);
}
return 0;
}
🔹11. strspn()
—— 计算前缀匹配长度
函数原型:
size_t strspn(const char *s, const char *accept);
参数说明:
s
:要检查的字符串。accept
:允许的字符集合。
返回值:
返回从开头开始连续属于 accept
中字符的最大长度。
示例:
#include <stdio.h>
#include <string.h>
int main() {
const char *str = "123abc";
const char *digits = "0123456789";
size_t len = strspn(str, digits);
printf("Prefix length: %zu\n", len); // 输出 3
return 0;
}
🔹12. strcspn()
—— 计算前缀不含某字符集的长度
函数原型:
size_t strcspn(const char *s, const char *reject);
参数说明:
s
:要检查的字符串。reject
:不允许出现的字符集合。
返回值:
返回从开头开始连续不属于 reject
中字符的最大长度。
示例:
#include <stdio.h>
#include <string.h>
int main() {
const char *str = "hello world";
size_t len = strcspn(str, " ");
printf("First word length: %zu\n", len); // 输出 5
return 0;
}
🔹13. strpbrk()
—— 查找第一个出现在指定字符集中的字符
函数原型:
char *strpbrk(const char *s, const char *accept);
参数说明:
s
:要查找的字符串。accept
:允许出现的字符集合。
返回值:
返回第一个出现在 accept
中的字符指针;未找到则返回 NULL
。
示例:
#include <stdio.h>
#include <string.h>
int main() {
const char *str = "abcdefg";
const char *chars = "xyzc";
char *p = strpbrk(str, chars);
if (p) {
printf("Found '%c' at index: %ld\n", *p, p - str);
} else {
printf("No match found\n");
}
return 0;
}
🔹14. strdup()
—— 字符串复制(非标准但常用)
函数原型(POSIX扩展):
char *strdup(const char *s);
参数说明:
s
:要复制的字符串。
返回值:
返回新分配的字符串副本,需手动调用 free()
释放。
示例:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
const char *original = "Dynamic copy";
char *copy = strdup(original);
if (copy) {
printf("Copy: %s\n", copy);
free(copy);
} else {
printf("Memory allocation failed\n");
}
return 0;
}
🔹15. strndup()
—— 指定长度的字符串复制(GNU扩展)
函数原型:
char *strndup(const char *s, size_t n);
参数说明:
s
:要复制的字符串。n
:最多复制的字符数。
返回值:
返回最多复制 n
个字符的新字符串副本。
示例:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
const char *original = "abcdefgh";
char *copy = strndup(original, 4);
if (copy) {
printf("Copy: %s\n", copy);
free(copy);
} else {
printf("Memory allocation failed\n");
}
return 0;
}
🔹16. strerror()
—— 根据错误码获取描述信息
函数原型:
char *strerror(int errnum);
参数说明:
errnum
:系统错误码(通常来自errno
)。
返回值:
返回对应错误码的可读性错误信息字符串。
示例:
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main() {
FILE *fp = fopen("nonexistent.txt", "r");
if (!fp) {
printf("Error: %s\n", strerror(errno));
}
return 0;
}
🔹17. strtok()
/ strtok_r()
—— 字符串分割
函数原型:
char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);
参数说明:
str
:待分割的字符串(首次调用传入)。delim
:分隔符字符串。saveptr
:保存内部状态(用于strtok_r
)。
示例(strtok):
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "apple,banana,orange";
char *token = strtok(str, ",");
while (token) {
printf("Token: %s\n", token);
token = strtok(NULL, ",");
}
return 0;
}
示例(strtok_r):
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "apple,banana,orange";
char *saveptr;
char *token = strtok_r(str, ",", &saveptr);
while (token) {
printf("Token: %s\n", token);
token = strtok_r(NULL, ",", &saveptr);
}
return 0;
}
🔹18. strcoll()
—— 按照当前区域设置比较字符串
函数原型:
int strcoll(const char *s1, const char *s2);
参数说明:
s1
:第一个字符串。s2
:第二个字符串。
返回值:
同 strcmp()
,但考虑了区域设置。
示例:
#include <stdio.h>
#include <string.h>
#include <locale.h>
int main() {
setlocale(LC_COLLATE, "zh_CN.UTF-8");
const char *s1 = "苹果";
const char *s2 = "香蕉";
int result = strcoll(s1, s2);
if (result < 0) {
printf("%s comes before %s\n", s1, s2);
} else if (result > 0) {
printf("%s comes after %s\n", s1, s2);
} else {
printf("%s and %s are equal\n", s1, s2);
}
return 0;
}
🔹19. strxfrm()
—— 将字符串转换为可排序形式
函数原型:
size_t strxfrm(char *dest, const char *src, size_t n);
参数说明:
dest
:转换后字符串的存放位置。src
:原始字符串。n
:最大写入字节数。
返回值:
返回转换后字符串的实际长度(不包括 \0
)。
示例:
#include <stdio.h>
#include <string.h>
#include <locale.h>
int main() {
setlocale(LC_COLLATE, "zh_CN.UTF-8");
const char *src = "苹果";
char dest[100];
size_t len = strxfrm(dest, src, sizeof(dest));
printf("Transformed string: %s (length: %zu)\n", dest, len);
return 0;
}
✅ 总结表格(含参数说明)
函数名 | 功能 | 参数说明 | 是否线程安全 |
---|---|---|---|
strcpy(dest, src) |
拷贝字符串 | dest : 目标缓冲区; src : 源字符串 |
❌ |
strncpy(dest, src, n) |
指定长度拷贝 | n : 最多拷贝字符数 |
❌ |
strcat(dest, src) |
拼接字符串 | dest : 原字符串; src : 要拼接的字符串 |
❌ |
strncat(dest, src, n) |
指定长度拼接 | n : 最多拼接字符数 |
❌ |
strcmp(s1, s2) |
比较字符串 | s1 , s2 : 待比较的两个字符串 |
✅ |
strncmp(s1, s2, n) |
指定长度比较 | n : 最多比较字符数 |
✅ |
strlen(s) |
获取字符串长度 | s : 要计算长度的字符串 |
✅ |
strchr(s, c) |
查找字符首次出现 | c : 要查找的字符 |
✅ |
strrchr(s, c) |
查找字符最后一次出现 | c : 要查找的字符 |
✅ |
strstr(haystack, needle) |
查找子字符串 | haystack : 主字符串; needle : 子字符串 |
✅ |
strspn(s, accept) |
匹配前缀字符 | accept : 允许字符集合 |
✅ |
strcspn(s, reject) |
匹配前缀不含字符 | reject : 不允许字符集合 |
✅ |
strpbrk(s, accept) |
查找任意字符首次出现 | accept : 允许字符集合 |
✅ |
strdup(s) |
复制字符串 | s : 要复制的字符串 |
❌ |
strndup(s, n) |
指定长度复制 | n : 最多复制字符数 |
❌ |
strerror(errnum) |
错误码转字符串 | errnum : 系统错误码 |
✅ |
strtok(str, delim) |
分割字符串 | str : 待分割字符串; delim : 分隔符 |
❌ |
strtok_r(str, delim, saveptr) |
线程安全分割 | saveptr : 保存状态指针 |
✅ |
strcoll(s1, s2) |
区域设置下比较 | s1 , s2 : 待比较字符串 |
✅ |
strxfrm(dest, src, n) |
转换为可排序形式 | dest : 结果缓冲区; src : 原字符串; n : 最大写入长度 |
✅ |
📌 提示建议:
- 使用时务必注意边界和空指针问题;
- 推荐使用更安全的替代函数如
strncpy
,strncat
; - 在多线程环境中优先使用
_r
版本(如strtok_r
); - 对字符串操作频繁的项目可考虑使用 C++ 的
std::string
或其他封装库。
研究学习不易,点赞易。
工作生活不易,收藏易,点收藏不迷茫 :)