当前位置:   article > 正文

C语言字符字符串函数:strcpy、strcat、strcmp介绍和模拟实现以及stnrcpy、strncat、strncmp介绍(近万字详解,建议三连收藏)_c语言 strcpy strcmp

c语言 strcpy strcmp

目录

1.strcpy(字符串拷贝函数)

1.1函数介绍

1.2函数使用示范 

1.3函数模拟实现 

2.strcat(字符串追加函数) 

 2.1函数介绍

 2.2函数使用示范:

2.3函数模拟实现 :

 2.4思考:字符串可以自己给自己追加吗?

 3.strcmp(字符串比较函数)

3.1函数介绍

3.2函数使用示范 

3.3函数模拟实现 

分割: 

4.strncpy(字符串拷贝函数,可以指定拷贝的字符数目) 

 4.1函数介绍

4.2函数使用示范 

5.strncat(字符串追加函数可以指定追加的字符数目) 

5.1函数介绍

5.2函数使用示范 

6.strncmp(字符串比较函数,可以限定比较的字符数)

6.1函数介绍 

6.2函数的实现 

7.strstr(字符串中找子字符串函数:图解实现)

7.1函数介绍

7.2函数演示使用

7.3函数模拟实现 

8.strtok函数(实现字符分割的函数) 

8.1函数介绍

8.2函数的使用举例 

9.strerror(打印错误信息函数) 

9.1函数介绍

9.2函数实现例子 

10.字符分类函数 

11.字符转换函数 

*10、11两种函数搭配实例 

12结语 


1.strcpy(字符串拷贝函数

1.1函数介绍

 

函数头文件:string.h

函数参数:① char * destination:拷贝目的空间的地址

                  ②const char * source:源字符串的地址

返回值类型:char*

返回值:返回目的字符串的地址也就是考到到某个地方,这个某个地方的地址。

函数功能:将源字符串直到\0以前的所有内容拷贝到目的空间,包括\0.

源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 拷贝到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变

1.2函数使用示范 

  1. int main()
  2. {
  3. char arr1[20] = { 0 };
  4. char arr2[] = "hello world";
  5. char arr3[6] = { 'a','b','c','d','e','f' };
  6. strcpy(arr1, arr2);
  7. printf("%s\n", arr1);
  8. strcpy(arr1, arr3);
  9. printf("%s\n", arr1);
  10. char arr4[6] = { 'a','b','c','d','e','\0' };
  11. strcpy(arr1, arr4);
  12. printf("%s\n", arr1);
  13. return 0;
  14. }

1.3函数模拟实现 

实现思想:

将目的空间的起始地址保存后,因为后续返回的是目的空间的地址。利用指针遍历将源字符串的内容赋值给目的空间,直到源字符串的指针解引用得到\0. 

参数部分:由于传递的是字符串的地址,所以用char* 类型的指针接收,对于源字符串来说,只是遍历但是不用修改其值,可以用const来修饰。接下来我们看实现

  1. char* my_strcpy(char* dest, const char* src)
  2. {
  3. char* ret = dest;
  4. //保存目的空间的地址,后续返回的是目的空间的地址
  5. //对于判断条件来说,要对指针解引用要保证指针的有效性,所以这里我们要断言一下
  6. assert(dest != NULL);
  7. assert(src != NULL);
  8. while (*src != '\0')
  9. {
  10. *dest = *src;
  11. src++;
  12. dest++;
  13. }
  14. *dest = *src;//\0
  15. return ret;
  16. }
  17. int main()
  18. {
  19. char arr1[20] = "hello world";
  20. char arr2[] = "xxxxx";
  21. my_strcpy(arr1, arr2);
  22. printf(“%s\n”,arr1);
  23. return 0;
  24. }

正是因为我们拷贝的时候将\0也拷贝进入了字符串1,所以1打印的时候只打印了前五个元素,但是内存里面是这样的

当然我们的循环遍历部分也可以改造得简单一些:

  1. while (*dest++ = *src++)
  2. {
  3. ;
  4. }

补充:

 返回值写成char* 是为了实现链式访问 比如:printf("%s\n",my_strcpy(arr1,arr2);
 因为返回的是目的空间首元素的地址

2.strcat(字符串追加函数) 

 2.1函数介绍

函数头文件:string.h

函数参数:① char * destination:追加目的空间的地址

                  ②const char * source:源字符串的地址

返回值类型:char*

返回值:返回目的字符串的地址也就是考到到某个地方,这个某个地方的地址。

函数功能:将源字符串直到\0以前的所有内容追加到目的空间,包括\0.

源字符串必须以 '\0' 结束。
会将源字符串中的 '\0' 追加到目标空间。
目标空间必须足够大,以确保能存放源字符串。
目标空间必须可变

 2.2函数使用示范:

引入例子:现在有目标空间里有hello,但是空间大,希望追加一个world,追加在后面
工作原理:找到目标地址的\0,然后追加
源和目标都有\0,都可修改,然后,目标空间要走足够大

  1. int main()
  2. {
  3. char arr1[20] = "hello";
  4. char arr2[] = "world";
  5. strcat(arr1, arr2);
  6. printf("%s\n", arr1);
  7. return 0;
  8. }

2.3函数模拟实现 :

实现思想:先利用目标空间首元素这个指针来找到目标空间字符串中的\0,然后从这个地址开始将源字符串通过指针遍历放到目的空间中,直到找到源字符串的\0. 

参数部分:由于传递的是字符串的地址,所以用char* 类型的指针接收,对于源字符串来说,只是遍历但是不用修改其值,可以用const来修饰。接下来我们看实现

  1. char * my_strcat(char* dest, const char* src)
  2. {
  3. //断言
  4. assert(dest);
  5. assert(src);//等于空指针就是0,为假就报错了
  6. char* ret = dest;
  7. //1.首先找目标空间中的\0
  8. while (*dest)
  9. {
  10. dest++;
  11. }
  12. while (*dest++ = *src++)
  13. {
  14. ;
  15. }
  16. return ret;
  17. }
  18. //
  19. int main()
  20. {
  21. char arr1[20] = "hello";
  22. char arr2[] = "world";
  23. //strcat(arr1, arr2);
  24. my_strcat(arr1, arr2);
  25. printf("%s\n", arr1);
  26. return 0;
  27. }

 实现效果:

 2.4思考:字符串可以自己给自己追加吗?

分析:当我们自己给自己追加的时候,字符串首元素的地址即是目的地址也是源地址,等目的地址找到\0, 此时开始追加,第一步就将h赋值给了\0的地址空间,让后des++,src++,依次赋值e,l,l....,最后我们发现\0就消失了,整个程序就陷入了死循环,当指针增加超过了这个数组的空间就越界了。

 3.strcmp(字符串比较函数

3.1函数介绍

函数头文件:string.h

函数参数:①const char * str1:字符串1的地址

                  ②,const char * str2:字符串2的地址

返回值类型:int

返回值:第一个字符串小于第二个字符串就返回一个<0的数

                第一个字符串等于第二个字符串就返回0

                第一个字符串大于第二个字符串就返回一个>0的数

函数功能:

 将 C字符串 str1 与 C字符串 str2 进行比较。从传递的地址处开始比较每个字符串的第一个字符(比较的是字符的ACSII码值)。如果它们彼此相等,则继续以下对,直到字符不同或同时达到\0字符。

3.2函数使用示范 

  1. int main()
  2. {
  3. int ret = strcmp("abq", "abq");
  4. printf("%d\n", ret);
  5. return 0;
  6. }

3.3函数模拟实现 

思想:通过两个指针循环遍历比较对应字符的acsii码值。

参数部分由于只做比较,不修改值所以可以用const修饰

  1. int my_strcmp(const char* str1, const char* str2)
  2. {
  3. while (*str1 == *str2)
  4. {
  5. if (*str1 == '\0')
  6. return 0;
  7. str1++;
  8. str2++;
  9. }
  10. if (*str1 > *str2)
  11. {
  12. return 1;
  13. }
  14. else
  15. return -1;
  16. }
  17. int main()
  18. {
  19. int ret = my_strcmp("abq", "abq");
  20. printf("%d\n", ret);
  21. return 0;
  22. }

分割: 

前面三个函数都是长度不受限制的字符串函数,只关心\0的位置,就是直接拷贝或者追加默认到结尾。
下面介绍长度受限制的字符串函数,唯一的区别就是可以控制拷贝的字符串长度,可以控制追加和比较的字符串的长度。这里做出介绍,不模拟实现,大家可以根据前三个函数和参数介绍进行使用与练习。

4.strncpy(字符串拷贝函数,可以指定拷贝的字符数目) 

 4.1函数介绍

函数头文件:string.h

函数参数:① char * destination:拷贝目的空间的地址

                  ②const char * source:源字符串的地址

                  ③num:无符号整型,表示要拷贝num个字符从源字符串到目标空间

返回值类型:char*

返回值:返回目的字符串的地址也就是考到到某个地方,这个某个地方的地址。

函数功能:将源字符串中前num个字符拷贝到目的空间,但是不会在拷贝完后补充\0
目标空间必须足够大,以确保能存放源字符串。目标空间必须可变

如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个。

4.2函数使用示范 

  1. int main()
  2. {
  3. char arr1[20] = { 0 };
  4. char arr2[] = "hello world";
  5. strncpy(arr1, arr2,3);
  6. printf("%s\n", arr1);
  7. return 0;
  8. }

看一下拷贝后的内存空间:

5.strncat(字符串追加函数可以指定追加的字符数目) 

5.1函数介绍

函数头文件:string.h

函数参数:① char * destination:追加目的空间的地址

                  ②const char * source:源字符串的地址

                  ③要追加的字符个数

返回值类型:char*

返回值:返回目的字符串的地址也就是考到到某个地方,这个某个地方的地址。

函数功能:将的前 num 个字符附加到目标,以及\0字符。只把要求的串的内容追加完成就行,追加完成会在后面补上\0.

5.2函数使用示范 

  1. int main()
  2. {
  3. char str1[20];
  4. char str2[20];
  5. strcpy(str1, "To be ");
  6. strcpy(str2, "orcd");
  7. strncat(str1, str2, 6);
  8. puts(str1);
  9. return 0;
  10. }

6.strncmp(字符串比较函数,可以限定比较的字符数)

6.1函数介绍 

函数头文件:string.h

函数参数:①const char * str1:字符串1的地址

                  ②,const char * str2:字符串2的地址

                  ③无符号整型num,表示要比较的前num个字符

返回值类型:int

返回值:第一个字符串小于第二个字符串就返回一个<0的数

                第一个字符串等于第二个字符串就返回0

                第一个字符串大于第二个字符串就返回一个>0的数

函数功能:

 将 C字符串 str1 与 C字符串 str2 进行比较。从传递的地址处开始比较每个字符串的第一个字符(比较的是字符的ACSII码值)。如果它们彼此相等,则继续以下对,直到字符不同或者第num个字符比较完

6.2函数的实现 

  1. int main ()
  2. {
  3. char str[][5] = { "R2D2" , "C3PO" , "R2A6" };
  4. int n;
  5. puts ("Looking for R2 astromech droids...");
  6. for (n=0 ; n<3 ; n++)
  7. if (strncmp (str[n],"R2xx",2) == 0)
  8. {
  9. printf ("found %s\n",str[n]);
  10. }
  11. return 0;
  12. }

7.strstr(字符串中找子字符串函数:图解实现)

7.1函数介绍

函数头文件:string.h

函数参数:① str1:目标字符串的地址

                  ②str2:被查找的字符串的地址

                

返回值类型:char*

返回值:返回指向 str1 中 str2 第一次出现的指针

函数功能:

查找子字符串

返回指向 str1 中 str2 第一次出现的指针,如果 str2 不是 str1 的一部分,则返回 null 指针。
匹配过程不包括终止 null 字符,但到此为止。

7.2函数演示使用

此示例在 str 中搜索“simple”子字符串,并将该词替换为“sample”。

输出:


This is a sample string
  1. int main ()
  2. {
  3. char str[] ="This is a simple string";
  4. char * pch;
  5. pch = strstr (str,"simple");
  6. if (pch != NULL)
  7. strncpy (pch,"sample",6);
  8. puts (str);
  9. return 0;
  10. }

7.3函数模拟实现 

 函数实现思想:

  1. char* my_strstr(const char* str1, const char* str2)
  2. {
  3. char* cp = (char*)str1;//用来记录从目标字符串开始匹配的位置
  4. char* s1 = cp;//用来在目标字符串中从开始匹配的位置进行匹配
  5. char* s2 = (char*)str2;//用来配合目标字符串之中的查找
  6. if (*str2 =='\0')
  7. {
  8. return (char* )str1;
  9. }
  10. while (*cp)//循环条件为当开始匹配的位置不为空指针,为空说明目标字符串已经遍历到了末尾了
  11. {
  12. //开始进行从匹配起始位置进行一个字一个字符的检查
  13. s1 = cp;//将起始位置赋值给s1,用来进行遍历匹配
  14. s2 = (char* )str2;
  15. while (*(char*)s1 && *(char*)s2 && *(char*)s1 == *(char*)s2)//
  16. {
  17. (char*)s1++;
  18. (char*)s2++;
  19. //当地址加加的时候,有可能目标地址来到末尾或者源字符串来到末尾,二者都应该结束循环,不进入循环
  20. //
  21. }
  22. if (*(char*)s2 == '\0')
  23. {
  24. return cp;//循环结束,只有源字符串遍历到最后一位找到了,返回目标字符串的起始匹配地址
  25. }
  26. cp++;//当循环结束没有找到,那就将起始匹配地址+!
  27. }
  28. return NULL;//当目标字符串遍历完了都没有匹配成功,那就找不到返回空指针
  29. }
  30. int main()
  31. {
  32. char arr1[] = "abbbcdef ";
  33. char arr2[] = "bbc";
  34. char* ret = my_strstr(arr1, arr2);
  35. if (ret != NULL)
  36. {
  37. printf("%s\n", ret);
  38. }
  39. else
  40. {
  41. printf("找不到\n");
  42. }
  43. return 0;
  44. }

8.strtok函数(实现字符分割的函数) 

8.1函数介绍

sep参数是个字符串,定义了用作分隔符的字符集合第一个参数指定一个字符串,它包含了0,个或者多个由sep字符串中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用\0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
如果strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL 指针


 

8.2函数的使用举例 

  1. int main()
  2. {
  3. char arr[] = "ouybnji@jdkdm.com";
  4. char copy[20];
  5. strcpy(copy, arr);
  6. char sep[] = { "@." };
  7. char* ret = NULL;
  8. for (ret = strtok(copy, sep); ret != NULL; ret = strtok(NULL, sep))
  9. {
  10. printf("%s\n", ret);
  11. }
  12. return 0;
  13. }

由于strtok函数会改变原字符串的内容,所以将字符串拷贝进copy数组里面,sep作为字符参数传入,把copy中的字符串以这两个字符进行分割,不管分隔符的顺序。第一次传参传入的1是copy数组的地址,函数找到分割符@将@改为\0,返回ouybnji的地址,第二次传参第一个函数即是空指针,函数里面保存的是j的地址,从这个地址去寻找分割符号,找到.,进行分割,返回j的地址,第三次传参传入空指针,函数里面保存了c的地址,找到\0没有找到分割符号返回null.

 

9.strerror(打印错误信息函数) 

9.1函数介绍

 库函数执行的时候会发生错误,会将错误码放在errnum这个变量中,errno是C语言提供的全局变量,错误信息表示的错误

函数:返回错误码,所对应的错误信息,返回来错误信息首字符的地址。

9.2函数实现例子 

10.字符分类函数 

这类函数很简单,控制字符属于什么关系,比如大写字符,小写字符,数字字符,如果判断为真就返回一个非0的值,如果判断为假函数就返回0.

这类函数的头文件包含为:ctype.h

我们来看一个:

函数:

检查字符是否为大写字母

检查参数 c 是否为大写字母。

返回值:如果 c 确实是大写的字母,则与零不同的值(即 true)。否则为零(即 false)。

函数有:

 函数 如果他的参数符合下列条件就返回真
iscntrl                任何控制字符
isspace                空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v'
isdigit                十进制数字 0~9
isxdigit                十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
islower                小写字母a~z
isupper                大写字母A~Z
isalpha                字母a~z或A~Z
isalnum                字母或者数字,a~z,A~Z,0~9
ispunct                标点符号,任何不属于数字或者字母的图形字符(可打印)
isgraph                任何图形字符
isprint                   任何可打印字符,包括图形字符和空白字符

11.字符转换函数 

int tolower ( int c );
int toupper ( int c )

函数功能:

将大写字母转换为小写字母

如果 c 是大写字母并且具有小写等效字母,则将 c 转换为小写等效字母。如果无法进行此类转换,则返回的值为 c 不变。

函数:将小写字母转换为大写字母

如果 c 是小写字母并且具有大写等效字母,则将 c 转换为大写等效字母。如果无法进行此类转换,则返回的值为 c 不变。

*10、11两种函数搭配实例 

  1. int main()
  2. {
  3. char arr[20] = { 0 };
  4. gets(arr);//这里使用gets函数获取字符串空格也可以直接读
  5. char* p = arr;
  6. while (*p)
  7. {
  8. if (isupper(*p))
  9. {
  10. *p = tolower(*p);
  11. }
  12. p++;
  13. }
  14. printf("%s\n", arr);
  15. return 0;
  16. }

12.结语 

以上就是本期的所有内容,知识含量蛮多,大家可以配合解释和原码运行理解。创作不易,大家如果觉得还可以的话,欢迎大家三连,有问题的地方欢迎大家指正,一起交流学习,一起成长,我是nicn,正在c++方向前行的新手,感谢大家的关注与喜欢。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/430010
推荐阅读
相关标签
  

闽ICP备14008679号