【一个示例学会的c语言】字符串处理函数
·
字符串处理是C语言编程中的基础且重要的部分。C标准库提供了一系列强大的字符串处理函数,掌握这些函数能大大提高编程效率。本文将详细介绍这些函数的用法、原理和注意事项。
头文件
所有字符串函数都定义在 <string.h> 头文件中:
#include <string.h>
1. 字符串长度函数
strlen - 计算字符串长度
size_t strlen(const char *str);
功能:返回字符串的长度(不包括结尾的空字符\0)
示例:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello World";
char *ptr = "C Programming";
printf("'%s' 长度: %zu\n", str, strlen(str)); // 11
printf("'%s' 长度: %zu\n", ptr, strlen(ptr)); // 13
printf("空字符串长度: %zu\n", strlen("")); // 0
return 0;
}
手写实现:
size_t my_strlen(const char *str) {
size_t len = 0;
while (*str != '\0') {
len++;
str++;
}
return len;
}
2. 字符串复制函数
strcpy - 字符串复制
char *strcpy(char *dest, const char *src);
功能:将src字符串复制到dest,包括结尾的\0
示例:
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Copy this string";
char dest[20];
strcpy(dest, src);
printf("源字符串: %s\n", src);
printf("目标字符串: %s\n", dest);
return 0;
}
手写实现:
char *my_strcpy(char *dest, const char *src) {
char *start = dest;
while ((*dest = *src) != '\0') {
dest++;
src++;
}
return start;
}
strncpy - 安全字符串复制
char *strncpy(char *dest, const char *src, size_t n);
功能:复制最多n个字符,防止缓冲区溢出
示例:
#include <stdio.h>
#include <string.h>
int main() {
char src[] = "This is a long string";
char dest[10];
strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0'; // 手动添加结束符
printf("安全复制: %s\n", dest);
return 0;
}
3. 字符串连接函数
strcat - 字符串连接
char *strcat(char *dest, const char *src);
功能:将src字符串连接到dest末尾
示例:
include <string.h>
int main() {
char str1[20] = "Hello";
char str2[] = " World";
strcat(str1, str2);
printf("连接结果: %s\n", str1); // "Hello World"
return 0;
}
手写实现:
char *my_strcat(char *dest, const char *src) {
char *start = dest;
// 找到dest的结尾
while (*dest != '\0') {
dest++;
}
// 复制src到dest末尾
while ((*dest = *src) != '\0') {
dest++;
src++;
}
return start;
}
strncat - 安全字符串连接
char *strncat(char *dest, const char *src, size_t n);
4. 字符串比较函数
strcmp - 字符串比较
int strcmp(const char *str1, const char *str2);
返回值:
-
<0:str1 < str2 -
=0:str1 == str2 -
>0:str1 > str2
示例:
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "apple";
char str2[] = "banana";
char str3[] = "apple";
// 比较不同字符串
printf("apple vs banana: %d\n", strcmp(str1, str2)); // 返回负值
printf("banana vs apple: %d\n", strcmp(str2, str1)); // 返回正值
printf("apple vs apple: %d\n", strcmp(str1, str3)); // 返回0
return 0;
}
手写实现:
int my_strcmp(const char *str1, const char *str2) {
while (*str1 && *str1 == *str2) {
++str1;
++str2;
}
return *(unsigned char*)str1 - *(unsigned char*)str2;
}
strncmp - 比较前n个字符
int strncmp(const char *str1, const char *str2, size_t n);
5. 字符串查找函数
strchr - 查找字符第一次出现
char *strchr(const char *str, int c);
示例:
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello World";
char *result;
result = strchr(str, 'o');
if (result != NULL) {
printf("找到 'o',位置: %ld,后续字符串: %s\n",
result - str, result); // 位置: 4, 字符串: "o World"
}
result = strchr(str, 'x');
if (result == NULL) {
printf("未找到 'x'\n");
}
return 0;
}
strstr - 查找子字符串
char *strstr(const char *haystack, const char *needle);
示例:
#include <stdio.h>
#include <string.h>
int main() {
char text[] = "C programming is fun";
char *found;
found = strstr(text, "program");
if (found != NULL) {
printf("找到子串,位置: %ld,内容: %s\n",
found - text, found); // "programming is fun"
}
return 0;
}
6. 字符串分割函数
strtok - 字符串分割
char *strtok(char *str, const char *delim);
示例:
#include <stdio.h>
#include <string.h>
int main() {
char text[] = "apple,banana,cherry,date";
char *token;
printf("原始字符串: %s\n", text);
printf("分割结果:\n");
// 第一次调用
token = strtok(text, ",");
while (token != NULL) {
printf("- %s\n", token);
token = strtok(NULL, ","); // 后续调用传NULL
}
return 0;
}
7. 内存操作函数
memcpy - 内存复制
void *memcpy(void *dest, const void *src, size_t n);
示例:
#include <stdio.h>
#include <string.h>
int main()
{
int src[] = {1, 2, 3, 4, 5};
int dest[5];
memcpy(dest, src, sizeof(src));
printf("复制结果: ");
for (int i = 0; i < 5; i++) {
printf("%d ", dest[i]); // 1 2 3 4 5
}
printf("\n");
return 0;
}
memset - 内存设置
void *memset(void *ptr, int value, size_t n);
示例:
#include <stdio.h>
#include <string.h>
int main() {
char buffer[10];
// 初始化为0
memset(buffer, 0, sizeof(buffer));
// 设置为特定值
memset(buffer, 'A', 5);
buffer[5] = '\0';
printf("结果: %s\n", buffer); // "AAAAA"
return 0;
}
综合应用示例
示例1:字符串处理工具函数
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// 去除字符串末尾的换行符
void trim_newline(char *str) {
int len = strlen(str);
if (len > 0 && str[len - 1] == '\n') {
str[len - 1] = '\0';
}
}
// 字符串反转
void reverse_string(char *str) {
int len = strlen(str);
for (int i = 0, j = len - 1; i < j; i++, j--) {
char temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
int main() {
char text[100];
printf("输入字符串: ");
fgets(text, sizeof(text), stdin);
trim_newline(text);
printf("原始: %s\n", text);
printf("长度: %zu\n", strlen(text));
reverse_string(text);
printf("反转: %s\n", text);
return 0;
}
示例2:安全字符串操作
#include <stdio.h>
#include <string.h>
void safe_string_operations() {
char buffer[20];
const char *source = "This is a very long string that might cause overflow";
// 安全复制
strncpy(buffer, source, sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
printf("安全复制: %s\n", buffer);
// 安全连接
char base[30] = "Hello";
const char *to_append = " World and everyone";
strncat(base, to_append, sizeof(base) - strlen(base) - 1);
printf("安全连接: %s\n", base);
}
int main() {
safe_string_operations();
return 0;
}
常见错误与注意事项
错误1:缓冲区溢出
// 错误示例
char dest[5];
char src[] = "This is too long";
strcpy(dest, src); // 缓冲区溢出!
// 正确做法
strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0';
错误2:未检查返回值
// 错误示例
char *result = strchr(str, 'a');
printf("找到: %s\n", result); // 如果result为NULL会崩溃
// 正确做法
char *result = strchr(str, 'a');
if (result != NULL) {
printf("找到: %s\n", result);
} else {
printf("未找到\n");
}
错误3:修改字符串常量
// 错误示例
char *str = "constant string";
str[0] = 'X'; // 未定义行为!
// 正确做法
char str[] = "modifiable string";
str[0] = 'X'; // 正确
性能优化技巧
-
避免重复计算长度:
// 不好 for (int i = 0; i < strlen(str); i++) { ... } // 好 int len = strlen(str); for (int i = 0; i < len; i++) { ... } -
使用memcpy处理大数据:
// 对于大型数据块,memcpy比strcpy更快 memcpy(dest, src, size); -
合理使用栈和堆:
// 小字符串用栈 char stack_str[100]; // 大字符串或动态长度用堆 char *heap_str = malloc(required_size);
总结
C语言的字符串函数虽然基础,但功能强大。掌握这些函数的关键点:
-
✅ 理解每个函数的参数和返回值
-
✅ 注意缓冲区安全和边界检查
-
✅ 区分字符串常量和可修改字符串
-
✅ 合理选择函数(strcpy vs strncpy等)
-
✅ 正确处理NULL指针和错误情况
通过熟练运用这些函数,你可以高效地处理各种字符串操作任务,写出更安全、更健壮的C语言程序。
更多推荐
所有评论(0)