外观
06.字符串与文件处理函数详解
约 1371 字大约 5 分钟
字符串处理函数C个人文件处理函数
2025-12-12
📌 字符串基础概念
在C语言中,字符串是以\0(空字符)结尾的字符数组。理解这一点是使用字符串函数的前提。
char str1[] = "Hello"; // 自动添加\0
char str2[6] = {'H','e','l','l','o','\0'}; // 手动添加\0📚 字符串长度相关函数
1. strlen - 获取字符串长度
功能:计算字符串长度(不包括结尾的\0)
#include <string.h>
char str[] = "Hello World";
size_t len = strlen(str); // len = 11注意:strlen时间复杂度为O(n),需要遍历整个字符串
2. sizeof vs strlen
char str[20] = "Hello";
printf("sizeof: %zu\n", sizeof(str)); // 输出20(数组大小)
printf("strlen: %zu\n", strlen(str)); // 输出5(实际内容长度)🔤 字符串拷贝函数
3. strcpy - 字符串拷贝
功能:将源字符串复制到目标字符串(包括\0)
char dest[20];
char src[] = "Hello";
strcpy(dest, src); // dest现在包含"Hello"4. strncpy - 安全字符串拷贝
功能:限制拷贝的字符数,防止缓冲区溢出
char dest[10];
char src[] = "Hello World";
strncpy(dest, src, sizeof(dest)-1);
dest[sizeof(dest)-1] = '\0'; // 手动确保以\0结尾🔄 字符串连接函数
5. strcat - 字符串连接
功能:将源字符串追加到目标字符串末尾
char dest[20] = "Hello";
char src[] = " World";
strcat(dest, src); // dest变成"Hello World"6. strncat - 安全字符串连接
char dest[15] = "Hello";
strncat(dest, " World!!!", sizeof(dest)-strlen(dest)-1);🔍 字符串比较函数
7. strcmp - 字符串比较
返回值:
<0:str1 < str2=0:str1 == str2>0:str1 > str2
char str1[] = "apple";
char str2[] = "banana";
int result = strcmp(str1, str2); // result < 08. strncmp - 比较前n个字符
if (strncmp(str1, str2, 3) == 0) {
// 前3个字符相同
}9. strcasecmp / stricmp - 不区分大小写比较
// 注意:这不是标准C函数,在有些平台需要特定头文件
if (strcasecmp("Hello", "hello") == 0) {
// 两者相等(忽略大小写)
}🎯 字符串查找函数
10. strchr - 查找字符首次出现位置
char str[] = "Hello World";
char *pos = strchr(str, 'o'); // 指向第一个'o'的位置
if (pos != NULL) {
printf("找到字符,位置:%ld\n", pos - str); // 输出4
}11. strrchr - 查找字符最后一次出现位置
char *last_pos = strrchr(str, 'o'); // 指向最后一个'o'12. strstr - 查找子串
char text[] = "C programming is fun";
char *found = strstr(text, "prog"); // 找到"prog"开始位置🛠️ 字符串分割函数
13. strtok - 字符串分割
注意:会修改原字符串,线程不安全
char str[] = "apple,banana,orange";
char *token = strtok(str, ",");
while (token != NULL) {
printf("%s\n", token);
token = strtok(NULL, ",");
}14. strtok_r - 线程安全版本
char *saveptr;
char *token = strtok_r(str, ",", &saveptr);
// 使用saveptr保存上下文📝 字符串转换函数
15. atoi / atol / atof - 字符串转数值
int num = atoi("123"); // 字符串转整数
long lnum = atol("123456"); // 字符串转长整数
double dnum = atof("3.14"); // 字符串转浮点数16. strtol / strtod - 更安全的转换
char *endptr;
long value = strtol("123abc", &endptr, 10);
// endptr指向无法转换的部分,可检测错误🧹 内存操作相关函数
17. memset - 内存设置
char buffer[100];
memset(buffer, 0, sizeof(buffer)); // 全部清零
memset(buffer, 'A', 10); // 前10字节设为'A'18. memcpy - 内存拷贝
char src[50], dest[50];
memcpy(dest, src, sizeof(src)); // 拷贝整个数组19. memcmp - 内存比较
if (memcmp(arr1, arr2, 100) == 0) {
// 前100字节相同
}📊 格式化字符串函数
20. sprintf / snprintf - 格式化输出到字符串
char buffer[50];
int n = sprintf(buffer, "Value: %d, Name: %s", 42, "Alice");
// 使用snprintf更安全
snprintf(buffer, sizeof(buffer), "Value: %d", 42);⚠️ 常见注意事项
缓冲区溢出防护
// 不安全的写法
char buf[10];
strcpy(buf, "这个字符串太长"); // 可能溢出!
// 安全的写法
strncpy(buf, src, sizeof(buf)-1);
buf[sizeof(buf)-1] = '\0';字符串结束符检查
// 自定义安全的字符串长度检查
size_t safe_strlen(const char *str, size_t max_len) {
size_t len = 0;
while (len < max_len && str[len] != '\0') {
len++;
}
return len;
}🔧 实际工作应用场景
场景1:解析配置文件
// 解析"key=value"格式
char line[] = "timeout=30";
char *key = strtok(line, "=");
char *value = strtok(NULL, "=");场景2:处理用户输入
// 安全读取并处理
char input[100];
fgets(input, sizeof(input), stdin);
input[strcspn(input, "\n")] = '\0'; // 移除换行符场景3:路径处理
// 获取文件名(最后一个/后的部分)
char *filename = strrchr(path, '/');
if (filename) filename++; // 跳过/
else filename = path;📝 最佳实践总结
- 始终检查缓冲区大小,使用带
n的安全版本(如strncpy、strncat) - 手动确保字符串以
\0结尾 - 使用
const修饰不会修改的字符串参数 - 注意字符串函数的返回值类型(
size_t、char*等) - 对于性能敏感的场景,避免在循环中重复调用
strlen - 使用现代编译器并开启警告(
-Wall -Wextra)
