本次来分享一下c语言中关于在实际项目中字符串的用途及一些关于字符串的基本操作和遇到的错误。
首先我们来看个场景,c语言中的库函数strcpy函数是如何实现的呢?
基本的思路就是循环遍历源字符串将源字符串中的每个字符都赋值给目标字符串,下面分享一下实现。
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
-
-
- //字符串copy函数
- void copy_str21(char *from, char *to)
- {
- for (;*from != '\0';from++, to++)
- {
- *to = *from;
- }
- *to = '\0';
- return;
- }
-
- void copy_str22(char *from, char *to)
- {
- for (;*from != '\0';)
- {
- *to++ = *from++;
- }
- *to = '\0';
- return;
- }
-
- void copy_str23(char *from, char *to)
- {
- while ((*to = *from) != '\0')
- {
- from++;
- to++;
- }
-
- }
-
- void copy_str24(char *from, char *to)
- {
- while ((*to++ = *from++) != '\0')
- {
- ;
- }
-
- }
-
- void copy_str25(char *from, char *to)
- {
- if (from == NULL || to == NULL)
- {
- return;
- }
- while (*to++ = *from++)
- {
- ;
- }
-
- }
-
- int main(int argc, char *argv[])
- {
- char *from = "abcd";
- char buf2[100];
- copy_str21(from, buf2);
- printf("buf2:%s \n", buf2);
-
- system("pause");
- return 0;
- }
-
这边可以看到实现并不复杂,但是需要注意几个容易出错的地方。
1、字符串是以'\0'字符结尾的,所以在跳出循环后需要将目标字符的结尾加上一个'\0'字符。
2、拷贝函数需要在开始的时候判断源字符串和目标字符串是否为空,如果为空的话就不能进行操作,否则会出现向保护地址写入值的情况,就会出现dump情况。

可以看到,如果没有分配空间的话就会出现dump的情况,所以在函数中需要进行判断在进行字符串操作。
接下来再看一个场景
char *p = "abcd11122abcd3332abcd333322qqq";
求字符串p中abcd出现的次数
即求子串在母串中出现的次数。
这边我们用到一个c语言库提供的函数strstr函数,用于找到子串在一个字符串中第一次出现的位置,在string.h头文件中。
即大概思路就是用strstr函数找到第一次出现子串后再进行偏移strlen(子串),循环到找不到子串就结束循环。
下面是实现
- int getCount(char *mystr,char *sub,int *ncount)
- {
- int ret = 0;
- int tmpCount = 0;
- char *p = mystr;
-
- if (mystr == NULL || sub == NULL || ncount == NULL)
- {
- ret = -1;
- return ret;
- }
- do
- {
- p = strstr(p, sub);
- if (p != NULL)
- {
- tmpCount++;
- p = p + strlen(sub);
- }
- else
- {
- break;
- }
-
- } while (*p != '\0');
-
- *ncount = tmpCount;
- return ret;
- }
-
- int main(int argc, char *argv[])
- {
- //初始化
-
- int ret;
- char *p = "abcd11122abcd3332abcd333322qqq";
- int count = 0;
- char sub[] = "abcd";
- ret = getCount(p, sub, &count);
-
- if (ret != 0)
- {
- printf("func");
- return ret;
- }
- printf("count : %d \n", count);
- system("pause");
- return 0;
- }
接下来再看一个场景
有一个字符串开头或结尾含有n个空格 (” abcdefgdddd ”),
欲去掉前后空格,返回一个新字符串。
这边可以用到"两个头堵"模型,
即定义两个变量分别从字符串头部和尾部进行偏移直到没有出现空字符为止,例如i=0,j=strlen(p)-1,
这边可以用c语言提供的函数isspace来进行判断
isspace
若判断字符ch为空空格、制表符或换行符,函数返回非零值,否则返回零值。
然后用j-i+1即可求得空格之间的字符串。
实现如下
- //去除字符串前后的空格
- //str所指向的内存空间可以被修改才行
- int trimSpace02(char *str)
- {
- //求非空格的长度
- char *p = str;
- int ncount = 0;
- int i, j;
-
- if (str == NULL )
- {
- printf("func trimSpace()error");
- return -1;
- }
- i = 0;
- j = strlen(p) - 1;
-
- while (isspace(p[i]) && p[i] != '\0')
- {
- i++;
- }
-
- while (isspace(p[j]) && p[j] != '\0')
- {
- j--;
- }
-
- ncount = j - i + 1;
-
- strncpy(str, str + i, ncount);
-
- str[ncount] = 0;
-
- return 0;
- }
-
- int main(int argc,char *argv[])
- {
- //求非空格的长度
- // char *p = " abcdefg ";
-
- // int num = 0;
- // getCount(p, &num);
-
- // printf("num:%d\n", num);
-
- char *p = " abcdefg ";
- char buf[1024] = " abcdefg ";
-
-
- trimSpace02(buf);
- printf("buf:%s\n", buf);
- //trimSpace(p, buf);
- //printf("buf:%s\n", buf);
- system("pause");
- return 0;
- }