C语言:字符串函数strlen、strcpy、strcat、strcmp、strstr的介绍讲解和底层代码模拟实现
快速了解strlen、strcpy、strcat、strcmp、strstr五个字符串函数和其底层代码逻辑
目录
1、strlen---计算字符串长度
size_t strlen( const char *string );
功能:计算字符串的长度并返回
注意事项:
1、字符串以'\0'结束标志,strlen函数返回的是'\0'前的字符个数(不包含'\0');
2、strlen函数的返回值是size_t(unsigned int),是无符号的;
3、参数所指向的字符串必须'\0'结尾。
4、头文件为<string.h>
使用案例:
代码:
#include <stdio.h>
#include <string.h>
int main()
{
char str[] = "abcde";//字符串后隐藏'\0',以\0'结尾
printf("%d\n", strlen(str));
return 0;
}
结果:

模拟实现:
int my_strlen(const char* str)
{
// 初始化一个整数变量len,用于存储字符串的长度,初始值为0。
int len = 0;
// 使用while循环遍历字符串,直到遇到空字符'\0'。
while (*str != '\0')
{
// 每次循环时,将len的值加1,表示又遍历到了一个字符。
++len;
// 将指针str向前移动到下一个字符的位置。
++str;
}
return len; // 当遇到空字符'\0'时,循环结束,函数返回len的值,即字符串的长度。
}
2、strcpy---字符串拷贝
char *strcpy( char *strDestination, const char *strSource );
功能:将源字符串(strSource)的内容(包括'\0')拷贝到目标字符串(strDestination)并返回目标字符串首字符地址
注意事项:
1、源字符串(strSource)必须以'\0'结尾
2、会将源字符串(strSource)中的'\0'拷贝到目标字符串(strDestination)
3、目标空间必须足够大,确保可以容纳得下源字符串(strSource)的内容
4、目标空间必须可修改
5、头文件为<string.h>
使用案例:
代码:
#include <stdio.h>
#include <string.h>
int main()
{
char dest[30] = {0};//目标空间确保可以存放源字符串
char src[] = "abcdefg";
char* ret = strcpy(dest, src);
//验证是否返回目标字符串首字符地址
printf("%s\n", ret);
//验证目标字符串是否修改
printf("%s\n", dest);
return 0;
}
结果:

模拟实现:
// 自定义的strcpy函数,用于将src字符串复制到dest字符串中
char* my_strcpy(char* dest, const char* src)
{
// 保存dest的起始地址,以便在函数结束时返回
char* ret = dest;
// 使用while循环遍历src字符串,直到遇到空字符'\0'
while ((*dest = *src) != '\0')
{
// 每次循环将dest和src指针都向后移动一位
++dest;
++src;
}
// 返回dest的起始地址
return ret;
}
3、strcat---字符串追加
char *strcat( char *strDestination, const char *strSource );
功能:将源字符串(strSource)追加到目标字符串(strDestination)的后面,并返回目标字符串首字符地址
注意事项:
1、源字符串(strSource)必须以'\0'结尾
2、目标空间必须足够大,确保可以容纳得下源字符串(strSource)的内容
3、目标空间必须可修改
4、不可自己追加自己,需要这样做则使用strncat
5、头文件为<string.h>
使用案例:
代码
#include <stdio.h>
#include <string.h>
int main()
{
char dest[30] = "abcd";//目标空间确保可以容纳得下源字符串
char src[] = "efg";
char* ret = strcat(dest, src);
//验证是否返回目标字符串首字符地址
printf("%s\n", ret);
//验证目标字符串是否被追加
printf("%s\n", dest);
return 0;
}
结果

模拟实现:
char* my_strcat(char* dest, const char* src)
{
char* ret = dest; // 保存dest的起始地址,以便在函数结束时返回
// 首先,定位到dest字符串的末尾,即找到第一个'\0'字符的位置
while (*dest != '\0')
{
// 遍历dest字符串,直到遇到结尾的空字符'\0'
++dest;
}
// 接下来,将src字符串的内容逐个字符地复制到dest字符串的末尾
while ((*dest = *src) != '\0')
{
// 每次循环后,dest指针指向下一个要写入的位置
++dest;
// 同时,src指针也指向下一个要读取的位置
++src;
}
// 函数返回dest字符串的起始地址(也即之前保存的ret值)
return ret;
}
4、strcmp---字符串比较
int strcmp( const char *string1, const char *string2 );
功能:比较字符串string1与字符串string2是否相等,如果string1大于string2,则返回大于0的值 ,如果string1小于string2,则返回小于0的值 ,string1等于string2,则返回0。
比较的方法:从string1和string2的首字符开始比较,比较它们的ASCII值,如果相等就比较下一个字符的ASCII值(包括\0)直到得出结果(两者比较到\0处后还相等,那就证明两字符串相等)
注意事项:
1、比较的两个字符串必需以'\0'结尾
2、了解其比较两字符串大小的方法,掌握模拟实现的代码逻辑
3、头文件为<string.h>
使用案例:
代码
#include <stdio.h>
#include <string.h>
int main()
{
char str1[30] = "abcd";
char str2[] = "abcd";
char str3[] = "dcba";
int ret1 = strcmp(str1, str2);
int ret2 = strcmp(str1, str3);
//返回值
printf("%d\n", ret1);
if (strcmp(str1, str2) == 0)
{
printf("str1 == str2\n");
}
else if (strcmp(str1, str2) > 0)
{
printf("str1 > str2\n");
}
else
{
printf("str1 < str2\n");
}
//返回值
printf("%d\n", ret2);
if (strcmp(str1, str3) == 0)
{
printf("str1 == str2\n");
}
else if (strcmp(str1, str3) > 0)
{
printf("str1 > str3\n");
}
else
{
printf("str1 < str3\n");
}
return 0;
}
结果

模拟实现:
int my_strcmp(const char* dest, const char* src)
{
// 循环比较两个字符串的每个字符,直到遇到空字符 '\0' 或两个字符不相同
while (*dest != '\0' && *src != '\0' && *dest == *src)
{
++dest; // 移动到下一个字符
++src; // 移动到下一个字符
}
// 返回两个字符串当前字符的差值
// 已转换为 unsigned char 类型,确保比较基于无符号值,避免符号扩展问题。
// 如果两个字符相同,则返回 0
// 如果 *dest 的 ASCII 码值大于 *src 的 ASCII 码值,则返回一个正数
// 如果 *dest 的 ASCII 码值小于 *src 的 ASCII 码值,则返回一个负数
return (unsigned char)*dest - (unsigned char)*src;
}
5、strstr---字符串查找
char *strstr(const char *haystack, const char *needle);
功能:strstr函数用于在一个字符串(haystack)中查找另一个字符串(needle)的首次出现位置。如果找到匹配的子字符串,则返回指向该位置的指针;如果未找到,则返回NULL。
注意事项:
- 头文件:使用
strstr函数需要包含头文件<string.h>。 - 大小写敏感:
strstr函数是大小写敏感的,即"A"和"a"被视为不同的字符。 - 空字符处理:
strstr函数会在遇到空字符(\0)时终止搜索,并且返回的指针不包括needle的结束符。 - 空指针检查:在调用
strstr之前,应确保传入的两个字符串指针都不是NULL,以避免潜在的空指针解引用错误。 - 内存相关性:返回的指针指向的是
haystack中的内存位置,因此在使用返回的指针时,要确保不会超出haystack的边界。
使用案例:
#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "Hello, World! This is a test.";
char str2[] = "World";
char* result;
result = strstr(str1, str2);
if (result != NULL) {
printf("Found '%s' in '%s' at position: %d, return: '%s' \n", str2, str1, result - str1, result);
}
else {
printf("'%s' not found in '%s'\n", str2, str1);
}
return 0;
}
结果:

模拟实现:
char* my_strstr(const char* haystack, const char* needle) {
// 如果 needle 是空字符串,则根据 strstr 的定义,返回 haystack 的起始位置。
if (*needle == '\0') {
return (char*)haystack;
}
// 遍历 haystack 字符串,直到找到匹配或到达字符串末尾。
while (*haystack != '\0') {
// 创建一个临时指针 haystack_temp,它指向当前 haystack 的位置,用于匹配 needle。
const char* haystack_temp = haystack;
// 创建一个临时指针 needle_temp,它指向 needle 的起始位置,用于匹配。
const char* needle_temp = needle;
// 尝试从当前 haystack_temp 位置开始匹配 needle。
while (*haystack_temp != '\0' && *needle_temp != '\0'
&& *haystack_temp == *needle_temp)
{
// 如果当前字符匹配,则移动到下一个字符继续匹配。
++haystack_temp;
++needle_temp;
}
// 如果已经匹配完整个 needle 字符串(needle_temp 到达末尾)
// 则返回 haystack 的当前位置。
if (*needle_temp == '\0') {
// 注意这里返回的是外层循环开始时 haystack 的位置。
return (char*)haystack;
}
// 如果没有匹配成功
//(needle_temp 没有到达末尾,但 haystack_temp 可能已经到达末尾或字符不匹配)
// 则移动 haystack 的主指针到下一个字符,继续搜索。
++haystack;
}
// 如果遍历完了 haystack 都没有找到匹配项,则返回 NULL。
return NULL;
}
更多推荐


所有评论(0)