C语言字符串函数手搓大全 | strcpy
、strcat
、strcmp
、strlen
、strchr
、strstr
全解
C 语言中对字符串的操作非常常见,而标准库虽然提供了方便的函数,如
strcpy
、strcat
等,但理解它们的底层实现,对于提升编程基础和内功非常重要。
本篇文将手写实现这些字符串函数,并配以详细注释,帮助掌握它们的实现原理。
前置知识
- C 字符串本质是以
\0
结尾的字符数组。 - 不能直接使用
==
比较字符串内容,需要逐字符比较。 - 对字符串的操作大多基于指针实现。
一、手搓 strcpy
— 字符串复制
char* my_strcpy(char* dest, const char* src) {char* original_dest = dest;while (*src != '\0') {*dest = *src; // 拷贝字符dest++;src++;}*dest = '\0'; // 别忘记添加字符串结束符return original_dest; // 返回最初的 dest 指针
}
说明:
- 将
src
字符串逐字符拷贝到dest
,直到遇到\0
。 - 使用
original_dest
保存原始指针,方便返回。
二、手搓 strcat
— 字符串拼接
char* my_strcat(char* dest, const char* src) {char* original_dest = dest;// 找到 dest 的结尾while (*dest != '\0') {dest++;}// 拷贝 src 到 dest 后面while (*src != '\0') {*dest = *src;dest++;src++;}*dest = '\0'; // 添加结束符return original_dest;
}
说明:
- 先找到
dest
的末尾位置,再从src
开始拼接。
三、手搓 strcmp
— 字符串比较
int my_strcmp(const char* str1, const char* str2) {while (*str1 && (*str1 == *str2)) {str1++;str2++;}return (unsigned char)*str1 - (unsigned char)*str2;
}
说明:
- 如果两个字符相等,则继续向后比较。
- 一旦有不同或遇到结束符,立即返回字符差值。
- 使用
(unsigned char)
强转,防止负数字符干扰比较结果。
四、手搓 strlen
— 计算字符串长度
int my_strlen(const char* str) {int length = 0;while (*str != '\0') {length++;str++;}return length;
}
说明:
- 遍历字符串直到遇到
\0
,计数即可.
五、手搓 strchr
— 查找字符第一次出现的位置
char* my_strchr(const char* str, int ch) {while (*str != '\0') {if (*str == (char)ch) {return (char*)str; // 找到字符,返回指针}str++;}return NULL; // 没找到
}
说明:
- 遍历字符串,每次比较当前字符与
ch
. - 找到就返回该位置指针,否则返回
NULL
.
六、手搓 strstr
— 查找子串
char* my_strstr(const char* haystack, const char* needle) {if (*needle == '\0') return (char*)haystack; // 空子串直接返回起始位置while (*haystack != '\0') {const char* h = haystack;const char* n = needle;// 比较两个字符串当前段是否完全匹配while (*h && *n && (*h == *n)) {h++;n++;}if (*n == '\0') {return (char*)haystack; // needle 完全匹配完,返回起始位置}haystack++; // 继续从下一个字符尝试匹配}return NULL; // 未匹配到子串
}
详细说明:
haystack
是原始字符串(如:“abcdefg”)needle
是你要找的子串(如:“cde”)- 关键点:
- 从
haystack
的每一个位置开始尝试与needle
逐字符匹配。 - 内层循环:只要字符相等就继续。
- 一旦
needle
遍历完成,即找到了子串,返回当前位置。 - 若失败,则外层继续向后滑动,直到整个
haystack
遍历完。
- 从
本质是暴力匹配(Brute-force),效率为 O(n * m),适合面试手写,不适合超大文本搜索(实际可用 KMP 等优化算法)
示例测试代码:
#include <stdio.h>char* my_strcpy(char*, const char*);
char* my_strcat(char*, const char*);
int my_strcmp(const char*, const char*);
int my_strlen(const char*);
char* my_strchr(const char*, int);
char* my_strstr(const char*, const char*);int main() {char buffer[100] = "Hello";const char* suffix = ", World!";const char* keyword = "World";// strcpychar copy[50];my_strcpy(copy, buffer);printf("strcpy: %s\n", copy);// strcatmy_strcat(buffer, suffix);printf("strcat: %s\n", buffer);// strcmpprintf("strcmp('abc', 'abd'): %d\n", my_strcmp("abc", "abd"));// strlenprintf("strlen('banana'): %d\n", my_strlen("banana"));// strchrchar* found = my_strchr("banana", 'n');if (found) {printf("strchr: Found 'n' at position: %ld\n", found - "banana");}// strstrchar* sub = my_strstr(buffer, keyword);if (sub) {printf("strstr: Found substring '%s' in \"%s\" at position: %ld\n", keyword, buffer, sub - buffer);} else {printf("strstr: Substring '%s' not found\n", keyword);}return 0;
}
✅ 总结
函数名 | 功能 | 返回值解释 |
---|---|---|
strcpy | 拷贝字符串 | 返回目标字符串指针 |
strcat | 拼接字符串 | 返回拼接后的目标字符串指针 |
strcmp | 字符串比较 | 相等返回 0,大返回正,小返回负 |
strlen | 计算字符串长度 | 返回字符个数(不含 \0 ) |
strchr | 查找字符 | 返回第一次出现的位置指针,找不到返回 NULL |
strstr | 查找子串 | 返回子串起始位置指针,找不到返回 NULL |
(完)