strcpy,strcmp,strstr,strcat,memcpy,memmove的模拟实现

来源:互联网 发布:阿里云服务器登陆账号 编辑:程序博客网 时间:2024/05/17 18:00

模拟实现这些库函数,首先要了解他们的功能,接下来我带你去了解

strcpy:

功能:字符串拷贝,把源字符串src,拷贝到目标空间dest中

要求:1.目标空间足够大,足够容得下src字符串。

            2.目标字符串可修改,源字符串不能修改。

            3.模拟实现strcpy返回值类型是char*,有返回值为了实现链式访问

具体实现:把src中内容拷贝到dest中,直到拷贝过去src'/0'结束

#define _CRT_SECURE_NO_WARNINGS#include<stdlib.h>#include<string.h>#include<assert.h>#include<stdio.h>char* my_strcpy(char*dest, const char*src){assert(dest!=NULL);assert(src!=NULL);//断言。判断两个指针是否为空指针,若为空指针后面解引用会使程序崩溃char*ret = dest;//创建一个临时指针记住新目标字符串首元素地址.//因为随着后面dest++,dest早已加到后面去了,因此需要一个变量记住它的地址while (*dest++ = *src++)//当把src的'/0'拷过去,while里面表达式为0;循环结束。{;}return ret;}int main(){char p1[20] = "abcde";char*p2 = "fgh";my_strcpy(p1, p2);printf("%s\n", p1);printf("%d\n", strlen(my_strcpy(p1, p2)));system("pause/n");return 0;}
模拟实现结果

2.strcat

功能:字符串追加,把源字符串src,追加到目标空间dest中

要求: 1.目标空间足够大,足够容得下src字符串。

            2.目标字符串可修改,源字符串不能修改。

            3.模拟实现strcat返回值类型是char*,有返回值为了实现链式访问

具体实现:strcat(dest,src)t把源字符src追加到目标空间dest中,首先要找dest中‘/0开始追加’,并且让src中字符串覆盖dest中‘/0’,然后直到追加到src的'/0'结束,也就说明strcat不能实现自己给自己追加,因为刚开始追加便把‘/0’覆盖,后面再也找不见结束的‘\0’

#include<stdlib.h>#include<string.h>#include<assert.h>#include<stdio.h>char* my_strcat(char*dest, const char*src){assert(dest); //断言。assert(src);//创建一个临时指针记住新目标字符串首元素地址.char*ret = dest;while (*dest != '\0')//找目标空间‘/0’{dest++;}while (*dest++ = *src++)//拷贝数据到目标空间{;}return ret;}int main(){char arr1[20] = "hello ";char arr2[] = "world";my_strcat(arr1, arr2);printf("%s\n", arr1);system("pause");return 0;}

模拟结果:


3 strcmp

功能:字符串比较函数

注意:s1和s2不能被修改,因此必须加上const 修饰

具体实现:若*s1的第一个字符的ASC||值大于*s2的第一个字符的ASC||码值,返回值为1,*s1的第一个字符的ASC||值小于*s2的第一个字符的ASC||码值,返回值为--1,相等就继续比较,直到遇到‘/0’.

#include<stdlib.h>#include<string.h>int my_strcmp(const char*s1, const char*s2){while (*s1 == *s2){if (*s1 == '\0')//两个字符串相等且遇见‘/0',说明比较结束,而且相等{return 0;}s1++;s2++;}if (*s1 - *s2>0)return 1;//如果*s1>*s2,返回1,说明字符串s1>字符串s2elsereturn -1; //如果*s2>*s1, 返回-1,说明字符串s2>字符串s1}int main(){char*p1 = "abdd";char*p2 = "abcd";int n = my_strcmp(p1, p2);printf("%d\n", n);system("pause");return 0;}

模拟结果:


4.strstr

功能:在字符串中查找子串,如果找到输出第一次找到子串的开始位置

注意:str和substr不能被修改用const 修饰

具体实现:要考虑到多种情况如下

                    1."abcdef"中找“bcd”     返回b的地址,输出bcdef

                    2."abcdef"中找“”           没有必要找,直接把abcdef输出

                   3.“abbcd”中找"bcd"       开始找str中b和substr中b相同,继续向后发现b和c不同,这时str应当退回去,从str中刚才开始匹配的下一个元素开始重新匹配,也就是str第                                                                三个元素开始继续匹配,如此重复,直到匹配成功。

#include<stdlib.h>#include<string.h>#include<stdio.h>#include<assert.h>char* my_strstr(const char*str, const char*substr){const char*s1 = str;const char*s2 = substr;const char*cur = str;//为了匹配不成功退回时能找到上次是从哪开始匹配的,接下从哪接着匹配assert(str);assert(substr);if (*substr == '\0'){return str;   //也就是上面所说第二种情况}while (*cur)//如果str和substr不相同时,让cur++;当有相同的时把cur赋给s1,substr赋给s2开始匹配如果相等,让s1,s2同时++比较,等到跳出里面那个while循环                    //判断  1.遇到*s2为’/0'而调出循环,说明匹配成功返回cur,{           //2,如果不是遇到'/0'说明匹配失败,让cur++,重新匹配,直到*cur为’/0'匹配彻底失败跳出最外面while循环永远找不到,则返回NULLs1 = cur;s2 = substr;while (*s1 == *s2){s1++;s2++;}if (*s2 == '\0')return cur;cur++;}return NULL;}int main(){char*p1="abdf";char*p2 = "bd";char*ret = strstr(p1, p2);printf("%s\n", ret);system("pause\n");return 0;}




 模拟结果:


5.memcpy

功能;由src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内。(src和dest内存不重叠)

注意:memcpy与strcpy区别:1.参数类型不同,memcpy可以是任何类型数据,而strcpy只能是字符串拷贝

                                                       2.strcpy是以‘/0’结束,停下来的位置不是你想要的。具体如下图。,而memcpy是具体要拷贝n个字节才结束

                                                    

      

        本来意思是想把36个字节都拷贝到arr2中,可结果却是拷贝到第二个字节就遇见“/0”   

                 

接下来实现 memcpy     

#include<stdlib.h>#include<string.h>#include<assert.h>  void *my_memcpy(void*dest, void*src, size_t n)  {  assert(dest);  assert(src);char*ret = dest;unsigned int i = 0;while(n--)//for (i = 0; i < n; i++)或者while(n--){*(char*)dest = *(char*)src;((char*)dest)++;//也可以是dest=(char*)dest+1;//或++(char*dest)((char*)src)++;//          src=(char*)src+1;//    ++(char*src)}return ret;}int main(){int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8 };int arr2[20] ; my_memcpy(arr2, arr1, 20); system("pause");return 0;}
   模拟实现结果                

 

6.memmove

功能;由src指向地址为起始地址的连续n个字节的数据复制到以dest指向地址为起始地址的空间内。(src和dest内存重叠)

注意:重叠部分:如果dest<src,  从前向后拷贝

                               如果dest>src,从后向前拷贝

           不重叠:两者都行

#include<stdlib.h>#include<string.h>#include<assert.h>void*my_memmove(void*dest, void*src, size_t count){assert(dest);assert(src);char*ret = dest;if (dest<src)while (count--)//从前向后拷贝{*(char*)dest = *(char*)src;((char*)dest)++;((char*)src)++;}else{while (count)//从后向前拷贝{*((char*)dest + count - 1) = *((char*)src + count - 1);count--;}}}int main(){int arr1[] = { 1, 2, 3, 4, 5, 6, 7, 8 };my_memmove(arr1, arr1 + 5, 5);system("pause");return 0;}
模拟结果:

从后向前拷贝那一部分代码也可以换为


以上是我对部分库函数的模拟实现,不太完善之处希望大家多多指证。以上没有strlen以及strncmp等的实现,后面会有一篇博客我会实现,其中包括strlen的三种实现方式。希望大家继续关注。

阅读全文
0 0
原创粉丝点击