当前位置:   article > 正文

字符串函数(3)【strstr函数的使用与模拟实现】【strtok的使用】【strerror的使用】_strstr 带字符串

strstr 带字符串

一.strstr函数的使用

这个函数是一个查找函数,比如在一个字符串中查找另一个字符串是否出现。也是有两个参数

这个函数返回的是字符串str2在字符串str1中第一次出现的位置。可以写一个代码来看一下。

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main()
  4. {
  5. char arr[] = " This is an apple ";
  6. const char* p = "is";//这是个常量字符串,最好加上const
  7. char* ret=strstr(arr, p);//这个函数的返回值是char*类型
  8. printf("%s", ret);
  9. return 0;
  10. }

这个输出的最终结果是is is an apple。这里还要提一下,如果str1里没有符合的字符串,那就返回一个空指针。

二.strstr函数的模拟实现

这个函数的模拟实现相对于其他的字符串函数来说就比较复杂了。我们知道,数组在传参的时候本质上传递的是指针。当我们把数组名传递给函数的的时候,就相当于把数组里第一个元素的首地址给传参了过去。那么当我们模拟实现strstr函数的时候,我们可以通过知道了数组的首地址,依次比较后面的元素,如果str1里完美的包括了str2里的元素,那么我们就可以把后面的元素打印出来,如图所示:

当然这种情况是最简单的一种情况。如果我要在abbbcdef里找到bbc呢?这个情况需要考虑的更多。为了让代码完美实现,就以这种情况来写这个代码。

  1. #include <stdio.h>
  2. char* my_strstr(const char* arr1, const char* arr2)
  3. {
  4. const char* s1 = NULL;
  5. const char* s2 = NULL;//防止野指针,用两个指针变量记录起始位置
  6. const char* cur = arr1;
  7. if (*arr2 == '\0')
  8. return (char*)arr1;//这种情况就是arr2里没有元素,直接返回arr1就行。arr1是const char* 类型,强制类型转换一下。
  9. while (*cur)//当*cur为'\0'时,循环结束。也就是arr1元素走到了最后了。
  10. {
  11. s1 = cur;
  12. s2 = arr2;//在后面的while执行完了一次循环之后,这里又会重新刷新一次s2。为了后面的再次判断做准备
  13. while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
  14. {
  15. s1++;
  16. s2++;//s1和s2继续往后走,继续判断是否相等.
  17. }
  18. if (*s2 == '\0')
  19. {
  20. return cur;//arr2已经在arr1里全部找到,此时的cur就是最终的结果。
  21. }
  22. cur++;//cur每次递增后,又重新赋值给了s1
  23. }
  24. return NULL;//没有符合条件的,返回空指针。
  25. }
  26. int main()
  27. {
  28. char arr[] = " This is an apple ";
  29. const char* p = "is";//这是个常量字符串,最好加上const
  30. char* ret=my_strstr(arr, p);//这个函数的返回值是char*类型
  31. printf("%s", ret);
  32. return 0;
  33. }

这个函数也有很多可以优化的地方,但是要实现起来会复杂许多,小编的实力现在还不足以写出来。这个函数的模拟函数虽然有点困难,但是真正理解之后也是可以很轻松。也是很有意思。

三.strtok函数的使用

简单的说,这个函数的作用就是分隔,也是有两个参数。

这个函数的用法我先描述一下。不想看的也可以直接跳过看后面的代码,直接用代码更好理解。(1)delimiters参数指向的是一个字符串,这个字符串就是我们所想要的分隔符集合(2)第一个参数str字符串,它包含的是0个或者多个由delimiters字符串中一个或者多个分隔符分割的标记(3)如果strtok函数找到了str里的下一个标记,会将其用'\0'结尾,返回一个指向这个标记的指针(4)strtok函数的第一个函数不为NULL,函数将找到str中的第一个标记,strtok函数将保存它在字符串中的位置(5)strtok函数的第一个函数如果为NULL函数将在同一个字符串中被保存的位置开始,查找下一个标记。(6)如果字符串中不存在更多的标记,则返回NULL指针。

我直接写一个简单的代码来看一下这个函数有什么作用。

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main()
  4. {
  5. char arr[] = "hello@world.hello";
  6. char arr1[30] = { 0 };
  7. strcpy(arr1, arr);
  8. const char* p = "@.";
  9. char* pa = strtok(arr1, p);
  10. printf("%s\n", pa);
  11. pa = strtok(NULL, p);
  12. printf("%s\n", pa);
  13. pa = strtok(NULL, p);
  14. printf("%s", pa);
  15. return 0;
  16. }

我用图来画一下

到这里,其实也能看出来这个函数是怎么实现的了。就是把除了分隔符之外的东西给打印出来。这个代码可以在改进一下。

  1. #include <stdio.h>
  2. #include <string.h>
  3. int main()
  4. {
  5. char arr[] = "hello@world.hello";
  6. char arr1[30] = { 0 };
  7. strcpy(arr1, arr);
  8. const char* p = "@.";
  9. char* pa = NULL;
  10. for (pa = strtok(arr1, p); pa != NULL; pa = strtok(NULL, p))
  11. {
  12. printf("%s\n", pa);
  13. }
  14. return 0;
  15. }

直接用一个for循环就OK了。注意为什么我的for循环的判断条件是pa!=NULL,大家可以参考我这里写的第六条,如果字符串中不存在更多的标记,则返回NULL指针。

四.strerror的使用

这个函数只有一个参数,这个函数可以把参数错误码对应的错误信息的字符串地址返回来。

在不同的系统和c语言标准库的实现中都规定了一些错误码,一般都是放在errno.h头文件中说明的,c语言程序启动的时候就会使用一个全局的变量errno来记录程序的当前错误码,只不过程序启动的时候errno是0,表示没有错误。在我们使用标准库中的某些函数发生了某些错误,就会将对应的错误码,存放在errno中,但是只有错误码,我们不知道错误信息,所以每一个错误码都是有对应的的错误信息的。而strerror函数就可以将错误对应的错误信息字符串返回。

我们可以写代码来看一下这些错误码对应的错误是什么?

这个函数的作用就是把错误码对应的错误信息给显示了出来。可以用这个函数来测试为什么我们的代码出现了错误。大家看

我的电脑里是没有test.txt文件的,所以必然会打开失败。但是如果我不知道为什么会打开失败,那么strerror这个函数就起到了作用。这个函数就直接会提醒我们为什么会打开失败,就像这里的没有这个文件。

这里我想在介绍一个函数叫做perror,这个函数相比于strerror就很简单了。还是这个代码我用perror来写。

  1. #include <stdio.h>
  2. int main()
  3. {
  4. FILE* pf = fopen("test.txt", "r");
  5. if (pf == NULL)
  6. {
  7. perror("lisi");
  8. return 1;
  9. }
  10. fclose(pf);
  11. return 0;
  12. }

这里就直接打印出来了错误信息,perror是有能力直接打印错误信息的。打印的时候,先打印传给perror的字符串,然后会打印冒号,再打印空格,最后会打印出错误信息。perror的作用相当于printf加strerror。既可以打印也可以得到错误信息。

感谢观看,如有错误,请多多指正。

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

闽ICP备14008679号