• C语言之字符函数&字符串函数篇(2)


    目录

    字符串查找

    strstr

    strstr的使用

    strstr的模拟实现 

    分析 

    考虑点 

    代码 

    strt

    strtok的使用

    循环改进 

    错误信息报告 

    strerror

    错误码的错误信息

    strerror的使用 

    perror

    字符操作

    字符分类函数

    字符转化函数


    今天我们接着讲字符串函数,也会讲到字符函数。关于下面的字符串函数我们将从:作用  头文件  参数 返回值 等方面去介绍。🆗🆗

    字符串查找

    strstr

     strstr - C++ Reference

    •  strstr_string string库函数,是在字符串中找字符串
    • const char * strstr ( const char * str1, const char * str2 ); 本质上就是在str1去查找str2strstr会返回str1中str2第一次出现的位置如果str1中没有str2,返回NULL
    • 头文件#include
    • 参数:两个字符串的指针
    • 返回值:str1中str2第一次出现的位置
    • strstr的模拟

    strstr的使用

    1. #include
    2. #include
    3. int main()
    4. {
    5. char arr1[] = "abcdefdhidefghi";
    6. char arr2[] = "def";
    7. const char* ret=strstr(arr1, arr2);
    8. //arr2第一次出现的位置
    9. if (ret == NULL)
    10. printf("找到不到");
    11. else
    12. printf("%s", ret);
    13. return 0;
    14. }

     

    strstr的模拟实现 

    分析 

    在我们的arr1中查找arr2中有很多种情况如下图: 

    当然最后一种情况我们还可以分为比较复杂的情况如下图:

     

    考虑点 

    所以综上我们需要考虑:

    •  str1和str2一开始就为空情况
    • 在遍历过程中*s1为'\0' *s2为'\0'情况
    • 创建str1和str2去记录 记录arr1和arr2的起始位置
    • 创建s1和s2去遍历查找匹配比较
    • 创建cp为了记录可能匹配成功的arr1中arr2第一次出现位置的地址
    • 两个循环条件
    • 当情况比较复杂的时候,请不要改变字符串起始位置的指针变量,创建其他的指针去查询。
    • const
    • assert

    代码 
    1. #include
    2. #include
    3. const char* my_strstr(const char* str1, const char* str2)
    4. {
    5. const char* cp;//记录开始匹配的位置,可能arr1中arr2第一次出现的位置
    6. const char* s1;//遍历str1指向的字符串
    7. const char* s2;//遍历str2指向的字符串
    8. //char*str1;
    9. //char*str2;
    10. assert(str1 && str2);
    11. cp = str1;//不改变初始位置的值
    12. while (*cp)//等于'\0'返回NULL
    13. {
    14. s1 = cp;//不改变cp的值
    15. s2 = str2;//不改变str2的值
    16. while (*s1 && *s2 && *s1 == *s2)
    17. //*s1 =='\0',arr1提前遇到'\0'找到不到了返回null
    18. //*s2 == '\0'arr2全部遍历匹配成功,返回此刻的cp
    19. //== 相等进入循环开始遍历匹配比较
    20. {
    21. s1++;
    22. s2++;
    23. //直到它们不相等跳出循环,找到下一个cp的位置继续查询
    24. }
    25. if (*s2 == '\0')
    26. return cp;
    27. //*s2 arr2全部匹配成功遇到'\0'
    28. //一开始*str2 == '\0'
    29. cp++;
    30. }
    31. return NULL;
    32. //一开始*str1 == '\0'
    33. //*s1 中途遇到'\0'(即arr1长度
    34. //arr1全部遍历完也没有匹配的
    35. }
    36. int main()
    37. {
    38. char arr1[] = "abbbcdef";
    39. char arr2[] = "bbc";
    40. const char* ret = my_strstr(arr1, arr2);
    41. //arr2第一次出现的位置
    42. if (ret == NULL)
    43. printf("找不到");
    44. else
    45. printf("%s", ret);
    46. return 0;
    47. }
    1. #include
    2. #include
    3. const char* my_strstr(const char* str1, const char* str2)
    4. {
    5. const char* cp;
    6. const char* s1;
    7. const char* s2;
    8. assert(str1 && str2);
    9. cp = str1;
    10. while (*cp)
    11. {
    12. s1 = cp;
    13. s2 = str2;
    14. while (*s1 && *s2 && *s1 == *s2)
    15. {
    16. s1++;
    17. s2++;
    18. }
    19. if (*s2 == '\0')
    20. return cp;
    21. cp++;
    22. }
    23. return NULL;
    24. }
    25. int main()
    26. {
    27. char arr1[] = "abbbcdef";
    28. char arr2[] = "bbc";
    29. const char* ret = my_strstr(arr1, arr2);
    30. if (ret == NULL)
    31. printf("找不到");
    32. else
    33. printf("%s", ret);
    34. return 0;
    35. }

    strt

    strtok - C++ Reference

    1. tsqxgd@yeah.net
    2. 192.168.101.23// IP地址_点分十进制的表示方法
    3. //IP地址本来是一个无符号的整数,这种整数不方便记忆,所以将这个整数换成点分十进制的表示方法
    4. 分割符:
    5. "@."//不讲究顺序
    6. "."
    char * strtok ( char * str, const char * sep );
    • 第二参数char *sep参数是个字符串,定义了用作分隔符的字符集合

    • 第一个参数char * str指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记

    • 头文件:#include

    • 有可分割的字符串返回标记的指针

    • 无可分割的字符串返回NULL

    • 分割过程:

    1. strtok函数找到str中的一个标记。

    2. 利用sep找到这个标记的分隔符,并将标记用 \0 结尾(将标记末尾的分隔符改变成'\0')

    3. 返回一个指向这个标记的指针

    4. 保存这个标记在字符串中的位置(以方便分割下一个标记)。

    5. 特别注意:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改

    • strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。

    • strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。

    • 如果字符串中不存在更多的标记,则返回 NULL 指针。停止分割

    • 因为切割字符串的过程中会改变原字符串的内容,所以我们可以先拷贝到临时空间,再对临时空间进行拷贝。

    • 若分割符和分割符相邻,会跳过。

    • 那到底strtok是怎样保存标记在字符串的位置呢?可能是static

    strtok的使用

    1. #include
    2. #include
    3. int main()
    4. {
    5. char arr[] = "tsqxgd@yeah.net";
    6. char buf[200] = { 0 };//放到临时的空间里,防止原arr被改变
    7. strcpy(buf, arr);
    8. char* sep = "@.";
    9. char* ret = strtok(buf, sep);
    10. printf("%s\n", ret);
    11. ret = strtok(NULL, sep);
    12. printf("%s\n", ret);
    13. ret = strtok(NULL, sep);
    14. printf("%s\n", ret);
    15. return 0;
    16. }

     

    循环改进 

    1. #include
    2. #include
    3. int main()
    4. {
    5. char arr[] = "tsqxgd@yeah.net";
    6. char buf[200] = { 0 };//放到临时的空间里,防止原arr被改变
    7. strcpy(buf, arr);
    8. char* sep = "@.";
    9. char* ret = NULL;//ret为空
    10. for (ret = strtok(buf, sep); ret != NULL; ret=strtok(NULL, sep))
    11. {
    12. printf("%s\n", ret);
    13. }
    14. return 0;
    15. }

    错误信息报告 

    strerror

    strerror - C++ Reference (cplusplus.com)

    •  strerror是库函数,将错误码翻译成错误信息,返回错误信息的字符串的起始地址
    • 头文件:#include
    • 参数:错误码(整型)
    • 返回值:返回错误信息的字符串起始地址
    • C语言中使用库函数的时候,如果发生错误,就会将错误码放在errno的变量中。
    • errno是一个全局变量,可以直接使用
    char * strerror ( int errnum );

    错误码的错误信息

    1. /* strerror example : error list */
    2. #include
    3. #include
    4. #include //必须包含的头文件
    5. int main()
    6. {
    7. int i = 0;
    8. for (i = 0; i < 10; i++)//错误码
    9. {
    10. printf("%d:%s\n", i, strerror(i));//错误信息
    11. }
    12. return 0;
    13. }

     

    strerror的使用 

    那上面只是我们查看一下各个错误码对应的错误信息,那在具体的情况下,我们应该怎样使用呢?

    1. /* strerror example : error list */
    2. //打开文件的例子
    3. //foopen以读的形式打开文件
    4. //如果文件存在,打开成功
    5. //如果文件不存在,打开失败
    6. #include
    7. #include
    8. #include //必须包含的头文件
    9. int main()
    10. {
    11. FILE* pFile;
    12. pFile = fopen("unexist.ent", "r");
    13. if (pFile == NULL)
    14. printf("打开文件失败原因是: %s\n", strerror(errno));
    15. else
    16. printf("打开文件成功\n");
    17. return 0;
    18. }

    perror

    perror - C++ Reference (cplusplus.com)

    •  直接打印错误码所对应的错误信息
    •  perror == printf +strerror
    1. //打开文件的例子
    2. //foopen以读的形式打开文件
    3. //如果文件存在,打开成功
    4. //如果文件不存在,打开失败
    5. #include
    6. #include
    7. #include //必须包含的头文件
    8. int main()
    9. {
    10. FILE* pFile;
    11. pFile = fopen("unexist.ent", "r");
    12. if (pFile == NULL)
    13. perror("打开文件失败");
    14. //== printf+strerror
    15. else
    16. printf("打开文件成功\n");
    17. return 0;
    18. }

    字符操作

    字符分类函数

    关于字符分类函数我们就不一一讲解,大家通过查询网站,和从参数,返回值等方面去分析这些函数。注意字符函数的头文件是#include

      (ctype.h) - C++ Reference (cplusplus.com)

     中文表格 

    字符转化函数

    (ctype.h) - C++ Reference (cplusplus.com)

    1. #include
    2. #include
    3. int main()
    4. {
    5. int ret = toupper('a');
    6. printf("%c\n", ret);
    7. ret = tolower(ret);
    8. printf("%c\n", ret);
    9. return 0;
    10. }

    我们用字符转化函数来实现一个简单的功能吧🆗🆗

    将arr字符串数组中的大写转化成小写

    1. #include
    2. #include
    3. int main()
    4. {
    5. char arr[] = "Text String";
    6. //全部转化成小写
    7. int* p = arr;
    8. while (*p)
    9. {
    10. if (isupper(*p))
    11. {
    12. *p = tolower(*p);
    13. }
    14. p++;
    15. }
    16. printf("%s", arr);
    17. return 0;
    18. }

     char类型可以放到int类型的变量中去;

     但是int类型不可以放到char类型的变量中去

    ✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正!下篇博文我们介绍内存函数。

    希望我们都能够熠熠生辉,旗鼓相当。

    代码------→【gitee:唐棣棣 (TSQXG) - Gitee.com

    联系------→【邮箱:2784139418@qq.com】

  • 相关阅读:
    关于我使用vue-quill-editor遇到的一些“坑”
    基于无人机的气象数据采集系统设计(Matlab代码实现)
    从月薪8k到月薪30k,自动化测试究竟该怎样学...
    PHP 简介
    基于Html的四季春茶销售网设计与实现
    GraalVM(云原生时代的Java)和IoT在边缘侧落地与实践
    C语言学习记录(九)之结构体
    亚马逊云科技 Build On-这可能是我离Amazon最近的一次
    软考高项-十大知识领域五大过程组图
    Nginx HTTP框架综述
  • 原文地址:https://blog.csdn.net/m0_74841364/article/details/133137547