• c语言之字符串


    本次来分享一下c语言中关于在实际项目中字符串的用途及一些关于字符串的基本操作和遇到的错误。

    首先我们来看个场景,c语言中的库函数strcpy函数是如何实现的呢?

    基本的思路就是循环遍历源字符串将源字符串中的每个字符都赋值给目标字符串,下面分享一下实现。

    1. #include <stdio.h>
    2. #include <string.h>
    3. #include <stdlib.h>
    4. //字符串copy函数
    5. void copy_str21(char *from, char *to)
    6. {
    7. for (;*from != '\0';from++, to++)
    8. {
    9. *to = *from;
    10. }
    11. *to = '\0';
    12. return;
    13. }
    14. void copy_str22(char *from, char *to)
    15. {
    16. for (;*from != '\0';)
    17. {
    18. *to++ = *from++;
    19. }
    20. *to = '\0';
    21. return;
    22. }
    23. void copy_str23(char *from, char *to)
    24. {
    25. while ((*to = *from) != '\0')
    26. {
    27. from++;
    28. to++;
    29. }
    30. }
    31. void copy_str24(char *from, char *to)
    32. {
    33. while ((*to++ = *from++) != '\0')
    34. {
    35. ;
    36. }
    37. }
    38. void copy_str25(char *from, char *to)
    39. {
    40. if (from == NULL || to == NULL)
    41. {
    42. return;
    43. }
    44. while (*to++ = *from++)
    45. {
    46. ;
    47. }
    48. }
    49. int main(int argc, char *argv[])
    50. {
    51. char *from = "abcd";
    52. char buf2[100];
    53. copy_str21(from, buf2);
    54. printf("buf2:%s \n", buf2);
    55. system("pause");
    56. return 0;
    57. }

    这边可以看到实现并不复杂,但是需要注意几个容易出错的地方。

    1、字符串是以'\0'字符结尾的,所以在跳出循环后需要将目标字符的结尾加上一个'\0'字符。

    2、拷贝函数需要在开始的时候判断源字符串和目标字符串是否为空,如果为空的话就不能进行操作,否则会出现向保护地址写入值的情况,就会出现dump情况。

     

    可以看到,如果没有分配空间的话就会出现dump的情况,所以在函数中需要进行判断在进行字符串操作。

    接下来再看一个场景

    char *p = "abcd11122abcd3332abcd333322qqq";
    求字符串p中abcd出现的次数

    即求子串在母串中出现的次数。

    这边我们用到一个c语言库提供的函数strstr函数,用于找到子串在一个字符串中第一次出现的位置,在string.h头文件中。

    即大概思路就是用strstr函数找到第一次出现子串后再进行偏移strlen(子串),循环到找不到子串就结束循环。

    下面是实现

    1. int getCount(char *mystr,char *sub,int *ncount)
    2. {
    3. int ret = 0;
    4. int tmpCount = 0;
    5. char *p = mystr;
    6. if (mystr == NULL || sub == NULL || ncount == NULL)
    7. {
    8. ret = -1;
    9. return ret;
    10. }
    11. do
    12. {
    13. p = strstr(p, sub);
    14. if (p != NULL)
    15. {
    16. tmpCount++;
    17. p = p + strlen(sub);
    18. }
    19. else
    20. {
    21. break;
    22. }
    23. } while (*p != '\0');
    24. *ncount = tmpCount;
    25. return ret;
    26. }
    27. int main(int argc, char *argv[])
    28. {
    29. //初始化
    30. int ret;
    31. char *p = "abcd11122abcd3332abcd333322qqq";
    32. int count = 0;
    33. char sub[] = "abcd";
    34. ret = getCount(p, sub, &count);
    35. if (ret != 0)
    36. {
    37. printf("func");
    38. return ret;
    39. }
    40. printf("count : %d \n", count);
    41. system("pause");
    42. return 0;
    43. }

    接下来再看一个场景

    有一个字符串开头或结尾含有n个空格 (”   abcdefgdddd    ”),

     欲去掉前后空格,返回一个新字符串。

    这边可以用到"两个头堵"模型,

    即定义两个变量分别从字符串头部和尾部进行偏移直到没有出现空字符为止,例如i=0,j=strlen(p)-1,

    这边可以用c语言提供的函数isspace来进行判断

    isspace
            若判断字符ch为空空格、制表符或换行符,函数返回非零值,否则返回零值。

    然后用j-i+1即可求得空格之间的字符串。

    实现如下

    1. //去除字符串前后的空格
    2. //str所指向的内存空间可以被修改才行
    3. int trimSpace02(char *str)
    4. {
    5. //求非空格的长度
    6. char *p = str;
    7. int ncount = 0;
    8. int i, j;
    9. if (str == NULL )
    10. {
    11. printf("func trimSpace()error");
    12. return -1;
    13. }
    14. i = 0;
    15. j = strlen(p) - 1;
    16. while (isspace(p[i]) && p[i] != '\0')
    17. {
    18. i++;
    19. }
    20. while (isspace(p[j]) && p[j] != '\0')
    21. {
    22. j--;
    23. }
    24. ncount = j - i + 1;
    25. strncpy(str, str + i, ncount);
    26. str[ncount] = 0;
    27. return 0;
    28. }
    29. int main(int argc,char *argv[])
    30. {
    31. //求非空格的长度
    32. // char *p = " abcdefg ";
    33. // int num = 0;
    34. // getCount(p, &num);
    35. // printf("num:%d\n", num);
    36. char *p = " abcdefg ";
    37. char buf[1024] = " abcdefg ";
    38. trimSpace02(buf);
    39. printf("buf:%s\n", buf);
    40. //trimSpace(p, buf);
    41. //printf("buf:%s\n", buf);
    42. system("pause");
    43. return 0;
    44. }

  • 相关阅读:
    微信小程序开启横屏调试
    21天学习挑战赛之Java面向对象分类、static
    网络货运平台服务模式,你真的了解吗?
    建立密切业务合作关系,供应商SRM系统助力企业做好新材料供应商品质管控
    手写数字识别--神经网络实验
    构建稳定高效的消息传递中间件:消息队列系统的设计与实现
    使用yum 安装mysql数据库
    【vue3】踩坑日记,vite与node版本对应(mac环境)
    【Spring Boot】Day03
    旋转矩阵转欧拉角,转四元数
  • 原文地址:https://blog.csdn.net/qq_45526401/article/details/127703630