C语言字符串函数
C语言字符串函数全面详解
我将系统性地讲解C语言中所有重要的字符串处理函数,包括它们的用法、参数、返回值和注意事项。
1. 字符串基础概念
字符串表示
在C语言中,字符串是以\0(空字符)结尾的字符数组。
char str1[] = "Hello"; // 自动添加\0
char str2[6] = {'H','e','l','l','o','\0'}; // 手动添加\0
char *str3 = "Hello"; // 字符串字面量(常量区)
2. 字符串长度函数
strlen
#include <string.h>
size_t strlen(const char *str);
- 功能:计算字符串长度(不包括
\0) - 示例:
char str[] = "Hello";
printf("长度: %zu\n", strlen(str)); // 输出: 5
- 注意:如果字符串没有
\0,会导致未定义行为
3. 字符串复制函数
strcpy
char *strcpy(char *dest, const char *src);
- 功能:将src复制到dest(包括
\0) - 危险:不检查目标缓冲区大小
char dest[10];
strcpy(dest, "Hello"); // 安全
// strcpy(dest, "This is too long"); // 危险!缓冲区溢出
strncpy
char *strncpy(char *dest, const char *src, size_t n);
- 功能:安全复制,最多复制n个字符
- 重要:可能不自动添加
\0
char dest[10];
strncpy(dest, "Hello World", 9);
dest[9] = '\0'; // 必须手动添加结束符
strdup(非标准但常用)
// 需要自己实现或检查编译器支持
char *strdup(const char *str) {
char *new_str = malloc(strlen(str) + 1);
if (new_str) strcpy(new_str, str);
return new_str;
}
4. 字符串连接函数
strcat
char *strcat(char *dest, const char *src);
- 功能:将src连接到dest末尾
char path[50] = "/home/";
strcat(path, "user"); // path变为"/home/user"
strncat
char *strncat(char *dest, const char *src, size_t n);
- 功能:安全连接,最多连接n个字符
- 优点:自动添加
\0
char buf[20] = "Hello";
strncat(buf, " World!!!", 6); // 只连接" World"
5. 字符串比较函数
strcmp
int strcmp(const char *str1, const char *str2);
- 返回值:
<0:str1 < str2=0:str1 = str2>0:str1 > str2
printf("%d\n", strcmp("apple", "banana")); // 负数
printf("%d\n", strcmp("apple", "apple")); // 0
strncmp
int strncmp(const char *str1, const char *str2, size_t n);
- 功能:比较前n个字符
// 比较前3个字符
if (strncmp("apple", "application", 3) == 0) {
printf("前3字符相同\n");
}
strcasecmp(不区分大小写,非标准)
// 需要包含相应头文件
#include <strings.h> // 或 <string.h>
int strcasecmp(const char *s1, const char *s2);
6. 字符串查找函数
strchr
char *strchr(const char *str, int c);
- 功能:查找字符c第一次出现的位置
char *p = strchr("hello", 'l'); // 指向第一个'l'
strrchr
char *strrchr(const char *str, int c);
- 功能:查找字符c最后一次出现的位置
char *p = strrchr("hello", 'l'); // 指向第二个'l'
strstr
char *strstr(const char *haystack, const char *needle);
- 功能:查找子串
char *p = strstr("hello world", "world"); // 找到"world"
strpbrk
char *strpbrk(const char *str, const char *accept);
- 功能:查找字符集中任意字符的第一次出现
char *p = strpbrk("hello", "aeiou"); // 找到'e'
7. 字符串分割函数
strtok
char *strtok(char *str, const char *delim);
- 功能:根据分隔符分割字符串
- 注意:会修改原字符串,非线程安全
char data[] = "name=john;age=25";
char *token = strtok(data, ";=");
while (token) {
printf("%s\n", token);
token = strtok(NULL, ";=");
}
strtok_r(可重入版本)
char *strtok_r(char *str, const char *delim, char **saveptr);
8. 内存操作函数(常用于字符串)
memcpy
void *memcpy(void *dest, const void *src, size_t n);
- 功能:内存复制(不处理重叠)
char src[] = "hello";
char dest[10];
memcpy(dest, src, 6); // 复制5字符+\0
memmove
void *memmove(void *dest, const void *src, size_t n);
- 功能:安全内存复制(处理重叠)
char str[] = "abcdef";
memmove(str + 2, str, 3); // 可以处理重叠区域
memset
void *memset(void *ptr, int value, size_t n);
- 功能:内存设置
char buffer[100];
memset(buffer, 0, 100); // 清零
memset(buffer, 'A', 10); // 前10字节设为'A'
memcmp
int memcmp(const void *ptr1, const void *ptr2, size_t n);
- 功能:内存比较
if (memcmp("apple", "apply", 3) == 0) {
printf("前3字节相同\n");
}
9. 字符串转换函数
字符分类函数(ctype.h)
#include <ctype.h>
isalpha(c); // 是否为字母
isdigit(c); // 是否为数字
isalnum(c); // 是否为字母或数字
islower(c); // 是否为小写
isupper(c); // 是否为大写
isspace(c); // 是否为空白字符
大小写转换
tolower('A'); // 返回'a'
toupper('a'); // 返回'A'
10. 数值转换函数
字符串转数值
#include <stdlib.h>
int atoi(const char *str); // 字符串转整数
double atof(const char *str); // 字符串转浮点数
long atol(const char *str); // 字符串转长整数
// 安全版本
long strtol(const char *str, char **endptr, int base);
double strtod(const char *str, char **endptr);
数值转字符串
#include <stdio.h>
char buffer[20];
int num = 255;
// 方法1: sprintf
sprintf(buffer, "%d", num);
// 方法2: 安全版本snprintf
snprintf(buffer, sizeof(buffer), "数值: %d", num);
11. 格式化字符串函数
sprintf / snprintf
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
char info[100];
sprintf(info, "姓名: %s, 年龄: %d", "John", 25);
snprintf(info, sizeof(info), "格式化..."); // 安全版本
12. 高级字符串处理技巧
安全字符串处理函数
// 安全的字符串复制
char* safe_strcpy(char *dest, const char *src, size_t dest_size) {
if (dest_size == 0) return dest;
strncpy(dest, src, dest_size - 1);
dest[dest_size - 1] = '\0';
return dest;
}
// 安全的字符串连接
char* safe_strcat(char *dest, const char *src, size_t dest_size) {
size_t dest_len = strlen(dest);
if (dest_len >= dest_size) return dest; // 没有空间了
strncat(dest, src, dest_size - dest_len - 1);
return dest;
}
字符串处理综合示例
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
void comprehensive_string_demo() {
// 1. 基本操作
char text[100] = "Hello World";
printf("原始: %s\n", text);
printf("长度: %zu\n", strlen(text));
// 2. 查找和替换
char *found = strstr(text, "World");
if (found) {
strncpy(found, "C Language", 10);
}
printf("替换后: %s\n", text);
// 3. 分割字符串
char data[] = "apple,banana,cherry";
char *token = strtok(data, ",");
while (token) {
printf("水果: %s\n", token);
token = strtok(NULL, ",");
}
// 4. 数值转换
char num_str[] = "123.45";
double num = atof(num_str);
printf("数值: %.2f\n", num);
// 5. 大小写转换
char mixed[] = "HeLLo";
for (int i = 0; mixed[i]; i++) {
mixed[i] = tolower(mixed[i]);
}
printf("小写: %s\n", mixed);
}
int main() {
comprehensive_string_demo();
return 0;
}
13. 常见错误和最佳实践
要避免的错误
// 错误1: 缓冲区溢出
char small[5];
strcpy(small, "This is too long"); // 危险!
// 错误2: 使用未初始化的指针
char *ptr;
strcpy(ptr, "hello"); // 未定义行为
// 错误3: 修改字符串字面量
char *p = "constant";
p[0] = 'C'; // 尝试修改只读内存,会崩溃
最佳实践
- 总是检查缓冲区大小
- 使用安全函数(带n的版本)
- 手动添加字符串结束符
- 验证函数返回值
- 使用const保护不应修改的字符串
这个全面的指南涵盖了C语言中最重要的字符串处理函数。掌握这些函数对于编写健壮、安全的C程序至关重要。

浙公网安备 33010602011771号