strcmp
首先该函数是比较函数其中,str1和str2是要进行比较的字符串。函数返回一个整数值来表示比较结果,返回值的含义如下:
若返回值为 0,表示两个字符串相等;
若返回值小于 0,表示str1小于str2;
若返回值大于 0,表示str1大于str2。
我们先看效果
int main() { char str1[] = "ABCD"; char str2[] = "ABCD"; char str3[] = "ABC"; char str4[] = "ABCDF"; int ret1 = strcmp(str1, str2); int ret2 = strcmp(str1, str3); int ret3 = strcmp(str1, str4); printf("%d\n", ret1); printf("%d\n", ret2); printf("%d\n", ret3); return 0; } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14
了解了效果后,我们来开始模拟
int my_strcmp(const char* str1, const char* str2) { int ret = 0; assert(str1 && str2); while (!(ret = *(unsigned char*)str1 - *(unsigned char*)str2) && *str2) { ++str1; ++str2; } if (ret < 0) return -1; else if (ret > 1) return 1; else return ret; } int main() { char str1[] = "ABCD"; char str2[] = "ABCD"; char str3[] = "ABC"; char str4[] = "ABCDF"; int ret1 = my_strcmp(str1, str2); int ret2 = my_strcmp(str1, str3); int ret3 = my_strcmp(str1, str4); printf("%d\n", ret1); printf("%d\n", ret2); printf("%d\n", ret3); return 0; } • 1 • 2 • 3 • 4 • 5 • 6 • 7 • 8 • 9 • 10 • 11 • 12 • 13 • 14 • 15 • 16 • 17 • 18 • 19 • 20 • 21 • 22 • 23 • 24 • 25 • 26 • 27 • 28 • 29 • 30
我们知道了strcmp的返回值是str1和str2进行比较后得出的,所以函数类型就是int型,在这里只是比较,不希望原字符串有任何改变,所以我们都用const来修饰两个参数,之后我们进入while循环来比较,因为当两个字符串的当前字符相等且尚未到达字符串的结束符时,继续执行循环体,即逐个比较两个字符串的字符,直到出现不同的字符或其中一个字符串到达结束符为止。所以我们设置了这样的循环条件,之后逐个比较str1和str2。
长度受限制的字符串函数
strncpy
该函数和strcpy函数的区别在于多了一个拷贝字符个数限制的条件,由于效果仅在于拷贝个数的限制,所以我们不在看效果,直接开始模拟。
char* my_strncpy(char* str1, size_t size, const char* str2) { char* ret = str1; assert(str1 && str2); int i = 0; while (i < size&&*str2) { *str1++ = *str2++; i++; } *str1 = '\0'; return ret; } int main() { char str1[] = "***************"; char str2[] = "hello world!"; int k = 0; printf("请输入拷贝字符个数:"); scanf("%d", &k); my_strncpy(str1, k, str2); printf("%s", str1); return 0; }
我们只需要多加一个size_t的参数,来限制拷贝个数即可,注意拷贝完成后,由于个数的限制没有到达结束,所以我们要令循环结束后的str指针也就是拷贝完成后的str指针所指向的内容是’\0’。
strncat
同样的这个函数也只是多了一个追加的个数限制条件。我们直接来模拟这个函数的实现。
char* my_strncat(char* str1, size_t size, const char* str2) { char* ret = str1; assert(str1 && str2); int i = 0; while (*str1) { str1++; } while (i < size&&*str2) { *str1++ = *str2++; i++; } *str1 = '\0'; return ret; } int main() { char str1[20] = "ABCD"; char str2[] = "EFGHIJKL"; int k = 0; printf("请输入追加字符的个数:"); scanf("%d", &k); my_strncat(str1, k, str2); printf("%s", str1); return 0; }
同样的,我们在知道了strcat函数的模拟以及strncpy函数的模拟,仅需要添加一个限制追加字符个数,并且将追加循环完成后str1所指向的内容赋值为’\0’即可。 其他的地方基本和上面几个函数的实现相似。
strncmp
这个函数与strcmp的区别也是多了一个比较个数的限制条件。为了防止大家误会这个函数的效果,我们来看一下这个函数的具体效果,再来模拟实现。
#include <stdio.h> #include <string.h> int main() { char str1[] = "hello"; char str2[] = "world"; int result = strncmp(str1, str2, 3); if (result == 0) { printf("前 3 个字符相等\n"); } else if (result < 0) { printf("str1 小于 str2\n"); } else { printf("str1 大于 str2\n"); } return 0; }
接下来,我们来具体模拟一下该函数
#include <stdio.h> #include <string.h> int my_strncmp(const char* str1, const char* str2, size_t size) { int ret = 0; assert(str1 && str2); int i = 0; while (i < size) { ret = *(unsigned char*)str1 - *(unsigned char*)str2; if (ret != 0) { return ret > 0 ? 1 : -1; } if (*str1 == '\0') break; ++str1; ++str2; i++; } return 0; } int main() { char str1[] = "hello"; char str2[] = "world"; int k = 0; printf("请输入str1和str2字符比较个数:"); scanf("%d", &k); int result = my_strncmp(str1, str2, k); if (result == 0) { printf("前 3 个字符相等\n"); } else if (result < 0) { printf("str1 小于 str2\n"); } else { printf("str1 大于 str2\n"); } return 0; }
首先也是多了一个限制比较个数的参数,但是有一点不同的是,由于比较完前k个字符,接下来的字符不一定是’\0’,所以我们的代码和实现strcmp有一点不同,一个一个字符来比较即可。
字符串查找函strstr
首先我们了解一下strstr函数的作用:
strstr 函数是C语言标准库 <string.h> 中提供的一个字符串处理函数,用于在一个字符串中查找指定子字符串的第一次出现位置。
函数原型如下:
char* strstr(const char* str1, const char* str2);
strstr 函数接受两个参数:str1 是要搜索的字符串,str2 是要查找的子字符串。
函数返回一个指向 str1 中第一次出现 str2 的位置的指针。如果未找到子字符串,返回 NULL。
来看一下效果:
int main() { char str1[] = "Hello, World!"; char str2[] = "World"; char* result = my_strstr(str1, str2); if (result != NULL) { printf("'%s' 第一次出现在 '%s' 中的位置是:%ld\n", str2, str1, result - str1); } else { printf("'%s' 未在 '%s' 中找到\n", str2, str1); } return 0; }
接下来我们来模拟实现一下。
#include <stdio.h> // 自定义实现 strstr 函数 char* my_strstr(const char* str1, const char* str2) { assert(str1); // 如果 str2 为空字符串,则直接返回 str1 if (*str2 == '\0') { return (char*)str1; } // 遍历 str1 while (*str1 != '\0') { const char* p1 = str1; const char* p2 = str2; // 在 str1 中查找 str2 while (*p1 == *p2 && *p1 != '\0') { p1++; p2++; } // 如果 p2 指向了 str2 的结尾,说明找到了 str2,返回位置 if (*p2 == '\0') { return (char*)str1; } // 在 str1 中继续查找 str1++; } // 没有找到 str2,返回 NULL return NULL; } int main() { char str1[] = "Hello, World!"; char str2[] = "World"; char* result = my_strstr(str1, str2); if (result != NULL) { printf("'%s' 第一次出现在 '%s' 中的位置是:%ld\n", str2, str1, result - str1); } else { printf("'%s' 未在 '%s' 中找到\n", str2, str1); } return 0; }
首先,我们需要两个字符串数组参数,在str1中寻找str2,由于我们只是寻找,并不希望原字符串发生改变,所以我们在接受参数时用const来修饰一下,如果str2指向的是空指针那么我们直接返回str1,如果不是进入我们的代码中,遍历str1,我们把str1和str2赋给p1和p2,然后设置一个如果存在才能进入的循环,然后给一个if语句,如果p2解引用等于‘\0’,说明str2到了末尾,也就是找到了,我们返回这个时候的str1指针所指向的位置,之后在if语句外str1++,如果没有碰到str2就遍历str1,这样我们最后遍历完str1,就能知道str2是否存在于str1中了。
总结
相信大家能看出来模拟这些函数有很多地方都是很相似的,那么就分享到这里,各位看客老爷万福金安。