strtok,strerror,memcpy,memmove,memcmp,memset详细解析及模拟实现

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 🐰strtok🐰strerror🐰memcpy🐰模拟实现memcpy🐰memmove🐰模拟实现memmove🐰memcmp🐰memset

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🐰strtok

🐰strerror

🐰memcpy

🐰模拟实现memcpy

🐰memmove

🐰模拟实现memmove

🐰memcmp

🐰memset


🐰strtok

strtok用于字符串的拆分,引用头文件为#include<string.h>

strtok的原型:

char * strtok ( char * str, const char * delimiters );

str:字符串的首地址

delimiters:分隔符

注意:返回类型是字符串的首地址

以下就是把2695855992.@qq.com分割成2695855992 qq com

"@.":分隔符

1. "@."分隔符
2. #include<stdio.h>
3. #include<string.h>
4. int main()
5. {
6. char arr[]="2695855992.@qq.com";
7. char buf[30]={0};
8. strcpy(buf,arr);
9. //    char* str=strtok(buf,"@.");//第一次调用时传字符串的首地址
10. //    printf("%s\n",str);
11. //    str=strtok(NULL,"@.");//第二次调用时传空指针
12. //    printf("%s\n",str);
13. //    str=strtok(NULL,"@.");//依次类推,只要不是第一次都得穿空指针
14. //    printf("%s\n",str);
15. for(char* str=strtok(buf,"@.");str!=NULL;str=strtok(NULL,"@."))//这里使用循环达到以上一样的效果
16.     {
17. printf("%s\n",str);
18.     }
19. return 0;
20. }

假如字符串是"aaa-bbb-ccc"

1.第一次调用strtok(),传入的参数str是要被分割的字符串{aaa - bbb -ccc},而成功后返回的是第一个子字符串{aaa};

2.而第二次调用strtok的时候,传入的第一个参数应该为NULL,使得该函数默认使用上一次未分割完的字符串继续分割 ,就从上一次分割的位置{aaa-}作为本次分割的起始位置,直到分割结束。

二.注意事项

这里首先需要强调的是strtok函数在进行字符串分解的时候,其第一个参数,即str是在变化的,就像前面说过的一样,其只是对原字符串(str)进行了调整,也就是改变了原字符串。由上面的例子来看,""2695855992@qq.com"是源字符串,在调用strtok对其分解结束后,字符串变成了"26958559920qq0com",其中的' @ ', ' . '替换成了'\0',也就是替换成了字符串结束标志字符,这样在打印或使用的时候都会使得前面的字符串成为一个看起来独立的字符串,即"2695855992"、"qq"、"com",这些字符串还是在源字符串中,只是后面都有了自己的字符串结束标志'\0'而已。

还有一点,strtok的第一个参数不能是常量字符串的指针,由于上面我们提到,strtok分割函数时,是要对原字符串做出改变的,但传入的是常量字符串,是无法做出改变的,从而导致错误

🐰strerror

strerror用于调用库函数失败时翻译错误信息,引用的头文件#include<string.h>

strerror的原型:

1. 
2. char * strerror ( int errnum );

errnum:调用库函数失败,返回的错误码

注意:返回错误码所对应的错误信息的首地址

1. #include<stdio.h>
2. #include<string.h>
3. #include<errno.h>
4. int main()
5. {
6.     FILE* pf=fopen("duck.txt.", "r");
7. if(pf==NULL)
8.     {
9. printf("%s\n",strerror(errno));//errno是一个全局变量,类型为整形,erron是一个错误码,系统调用出错的时候,会设置一个错误码。因为C语言没有异常处理机制,所以要依靠错误码进行异常情况的处理。
10.     }
11. return 0;
12. }

4C1CC629-F2EF-4575-A04C-66A4509B9156.jpeg

我的电脑中没有duck.txt这个文件,所以它会返回一个错误的信息说的就是不存在这样的文件,这就是strerror对错误码翻译

其实我们还可以自己定义错误码,去查看错误码在库函数所对应的信息,例如

1. #include<stdio.h>
2. #include<string.h>
3. int main()
4. {
5. printf("%s\n",strerror(0));
6. printf("%s\n",strerror(1));
7. printf("%s\n",strerror(2));
8. printf("%s\n",strerror(3));
9. printf("%s\n",strerror(4));
10. printf("%s\n",strerror(5));
11. printf("%s\n",strerror(6));
12. printf("%s\n",strerror(7));
13. printf("%s\n",strerror(8));
14. return 0;
15. }
16.

F07264B2-DE54-4EA8-81ED-A3BAA3AB11D3.jpeg

🐰memcpy

memcpy用于内存拷贝(什么类型数据都可以),引用头文件#include<string.h>

memcpy的原型:

void * memcpy ( void * destination, const void * source, size_t num );

destination:目标空间

source:拷贝空间

num:拷贝字节数

注意:返回目标空间的首地址

注:void*是通用指针类型,可以接受任意类型的数据,不能进行解引用操作

1. #include<stdio.h>
2. #include<string.h>
3. int main()
4. {
5. int arr[]={1,2,3,4,5,6,7,8,9,0};
6. int brr[20]={0};
7. memcpy(brr,arr,20);//在arr中拷贝了20个字节
8. for(int i=0;i<5;i++)
9.     {
10. printf("%d ",brr[i]);
11.     }
12. return 0;
13. }
14. 结果:1 2 3 4 5

🐰模拟实现memcpy

1. #include<stdio.h>
2. #include<string.h>
3. void* my_memcpy(void* dest,void* src,size_t num)//将传入数据类型强制转化为字符类型,然后一个字节一个字节进行拷贝,这样就可以实现任何数据类型的拷贝
4. {
5. void* ret=dest;
6. while(num--)
7.     {
8.         *(char*)dest=*(char*)src;
9.         dest=(char*)dest+1;
10.         src=(char*)src+1;
11.     }
12. return ret;
13. }
14. int main()
15. {
16. int arr[]={1,2,3,4,5,6,7,8,9,0};
17. int brr[20]={0};
18. my_memcpy(brr,arr,20);
19. for(int i=0;i<5;i++)
20.     {
21. printf("%d ",brr[i]);
22.     }
23. return 0;
24. }

🐰memmove

memove用于内存的拷贝(和memcpy一样实现内存拷贝,但是由于编译器的原因,memcpy不能实现拷贝空间和目标空间在一个空间,而memmove可以实现),引用头文件#include<string.h>

memove的原型:

void * memmove ( void * destination, const void * source, size_t num );

destination:目标空间

source:拷贝空间

num:拷贝字节数

注意:返回目标空间的首地址

1. #include<stdio.h>
2. #include<string.h>
3. int main()
4. {
5. int arr[]={1,2,3,4,5,6,7,8,9,0};
6. int brr[20]={0};
7. memmove(arr+2,arr,20);
8. for(int i=0;i<5;i++)
9.     {
10. printf("%d ",arr[i]);
11.     }
12. return 0;
13. }

🐰模拟实现memmove

1. #include<stdio.h>
2. #include<string.h>
3. void* my_memmove(void* dest,void* src,size_t num)
4. {
5. void* ret=dest;
6. if(dest>src)//如果目标空间的首地址大于拷贝空间的首地址,就得实现从后往前拷贝
7.     {
8. while(num--)
9.         {
10.             *((char*)dest+num)=*((char*)src+num);//一个字节一字节拷贝
11.         }
12.     }
13. else{
14. while(num--)//如果目标空间的首地址小于或等于拷贝空间的首地址,就得实现从前往后拷贝
15. //一个字节一字节拷贝        
16.         {
17.             *(char*)dest=*(char*)src;
18.             dest=(char*)dest+1;
19.             src=(char*)src+1;
20.         }
21.     }
22. return ret;
23. }
24. int main()
25. {
26. int arr[]={1,2,3,4,5,6,7,8,9,0};
27. int brr[20]={0};
28. my_memmove(arr,arr+2,20);
29. for(int i=0;i<5;i++)
30.     {
31. printf("%d ",arr[i]);
32.     }
33. return 0;
34. }

🐰memcmp

memcmp用于空间的比较函数(字符类型,整形,浮点型...),引用头文件#include<string.h>

memcmp的原型:

int memcmp ( const void * ptr1, const void * ptr2, size_t num );

ptr1:比较的空间的首地址

ptr2:比较空间的首地址

num:比较的字节数

注意:返回类型为整形    

ptr1>ptr2 返回大于0的数

ptr1==ptr2返回0

ptr1<ptr2   返回小于0的数

🐰memset

memset用于空间设置函数,引用头文件#include<string.h>

memset的原型:

void * memset ( void * ptr, int value, size_t num );

ptr:设置的空间

value:设置成的值

num:设置的字节数

注意:返回设置空间的首地址

1. #include<stdio.h>
2. #include<string.h>
3. int main()
4. {
5. int arr[]={1,2,3,4,7};//01 00 00 00 02 00 00 00
6. memset(arr,0,5);//将arr的5个字节设置成0
7. for(int i=0;i<5;i++)
8.     {
9. printf("%d ",arr[i]);
10.     }
11. return 0;
12. }
13. 结果:0 0 3 4 7

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸  

文章

相关文章
|
4月前
|
C语言
C语言:内存函数(memcpy memmove memset memcmp使用)
C语言:内存函数(memcpy memmove memset memcmp使用)
|
3月前
10分钟让你学会内存函数:memcpy,memmove,memset,memcmp的用法及模拟实现。
10分钟让你学会内存函数:memcpy,memmove,memset,memcmp的用法及模拟实现。
49 2
|
4月前
|
存储 算法 C语言
C库函数详解 - 内存操作函数:memcpy()、memmove()、memset()、memcmp() (一)
`memcpy()` 和 `memmove()` 是C语言中的两个内存操作函数。 `memcpy()` 函数用于从源内存区域复制指定数量的字节到目标内存区域。它不处理内存重叠的情况,如果源和目标区域有重叠,结果是未定义的。函数原型如下: ```c void *memcpy(void *dest, const void *src, size_t num); ```
167 6
|
1月前
【C初阶】内存函数:memcpy+memmove+memset+memcmp
【C初阶】内存函数:memcpy+memmove+memset+memcmp
|
4月前
|
存储 C语言
C库函数详解 - 内存操作函数:memcpy()、memmove()、memset()、memcmp() (二)
`memset()`是一个C语言库函数,用于将指定内存区域的字节设置为特定值。函数原型为`void *memset(void *ptr, int value, size_t num)`,参数分别为指向内存起始位置的指针、要设置的值和设置的字节数。`memcmp()`函数则用于比较两个内存区域,返回值表示比较结果,原型为`int memcmp(const void *ptr1, const void *ptr2, size_t num)`。它比较指定字节数的内存,并根据比较结果返回整数值。
46 4
|
4月前
模拟实现memcpy,memmove,memset,memcmp
memcpy void * memcpy ( void * destination, const void * source, size_t num );
22 1
|
10月前
|
存储 Cloud Native Linux
C++ strcpy、sprintf与memcpy的区别
C++ strcpy、sprintf与memcpy的区别
|
存储 安全 编译器
【C语言】memcpy,memmove,memcmp,memset函数详解
【C语言】memcpy,memmove,memcmp,memset函数详解
【C语言】memcpy,memmove,memcmp,memset函数详解
C实现字符操作函数,strcpy, strcat, strcmp, memcpy
C实现字符操作函数,strcpy, strcat, strcmp, memcpy
40 0
|
4月前
|
存储 安全
内存函数(memcpy、memmove、memset、memcmp)你真的懂了吗?
内存函数(memcpy、memmove、memset、memcmp)你真的懂了吗?
167 0
内存函数(memcpy、memmove、memset、memcmp)你真的懂了吗?