C神功秘籍第三章(字符串函数详解)(第二节)

上节因为临时有事没有写完就发了,在下在这里给诸位道友抱歉了,话不多说我们上节介绍了两个字符串函数的用法和模拟实现,接下来就续前节探讨。

补充:上节的strlen函数的返回值是size_t(unsigned int)无符号整形,这是库函数用typedef关键字定义的一个类型,所以这个函数要注意有坑。

如下代码:

#include<stdio.h>
int main()
{
if(strlen("abc")-strlen("abcdef")>0)
{
    printf("hehe\n");
}
else
{
    printf("haha\n");
}
return 0;
}

        上面代码结果是:hehe,因为是strlen函数是无符号整形,无符号整形不存在负数,所以即使abc确实比abcdef小相减还是>0的。

3.strcat函数

        说明:此函数有类似于strcpy函数,但是strcpy函数是把字符串拷贝到首字符开始的元素,而strcat函数是把字符串追加到目的字符串从\0开始的位置。参数1:目的字符串,参数2:原字符串

        思路:既然是从目的字符串\0的位置开始追加,那我们就得先找到目的字符串\0的位置,然后就开始追加。

实现代码如下:

#include<stdio.h>
#include<assert.h>
char* my_strcat(char* str1,const char* str2)
{
    assert(str1!=NULL && str2!=NULL);    //确定两个指针有效性
    char* ret=str1;    //因为后面str1的元素地址会发生变化,所以初始化首元素地址方便后面参数返回打印。
    while(*str1 !='\0')    //找到\0位置
    {
        str1++;        //这里不能把自增放在while条件里,因为我们是要找\0位置,最后一次判断出来之前他会自增,导致出来后不是\0位置而是\0后面的地址。
    }
    while(*str1++=*str2++)        //把str2的元素追加到str1
    {
        ;
    }
    return ret;    //返回str1初始地址。
}
int main()
{
   char arr1[30]="hello";    //注意这里一定要给数组空间大小,默认就是刚好他现在存储的大小,后面追加不指定大小会装不下的。
   char arr2[]="world";
   my_strcat(arr1,arr2);
   printf("%s\n",arr1);
   return 0;
}

4.strcpy函数

        功能:此函数类似于上个strcat函数,还要简单一些,不用找\0直接从首元素开始拷贝,参数1:目的字符串,参数2:要拷贝的字符串。

        思路:直接从首元素开始拷贝即可。

实现代码如下:

#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* str1,const char* str2)
{
assert(str1!=NULL && str2!=NULL)
char* ret=str1;
while(*str1++=*str2++;)
{
    ;
}
return ret;
}
int main()
{
char arr1[15]="abc";        //跟strcat函数一样要初始化数组大小,保证能够放得下两个字符串。
char arr2[]="def";
my_strcpy(arr1,arr2);
printf("%s\n",arr1);
return 0;
}

重难点:5.strstr函数

        说明:此函数是一个查找子串函数, 参数1:进行查找的字符串,参数2:要查找的子字符串。若查找到返回地址,查找不到就返回空指针。

        思路:这种函数比较复杂,要分情况讨论的多,第一种情况是arr1比arr2小那么就说明arr2绝对不是arr1的子字符串,还有一种情况就是他们两个字符串比较相等且都为\0就说明他们arr2是arr1的子字符串,注意查找过程中要保留初始查找地址,好进行下一次查找。

        具体代码如下:

#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1,const char* str2)
{
    assert(str1!=NULL && str2!=NULL);
    char* s1=NULL;
    char* s2=NULL;
    char* cor=(char*)str1;
if(*str2=='\0')
{
return str1;        //每个字符串都有\0,str2一定是str1的子字符串。
}
while(cor)        //若cor(str1)比子字符串小,str2一定不是str1的子字符串
{
    s1=cor;
    s2=(char*)str2;
    while((*s1 != '\0' && *s2 != '\0') && (*s1==*s2))    //若s1和s2都不等于\0且相等
    {
    s1++;
    s2++;
    }
    if(*s2=='\0')
    {
    return cor;        //若子字符串已经到\0说明str2是str1的子字符串
    }
    else if(*s1=='\0')
    {
    return NULL;    //若str1比str2提前到\0那么str2一定不是str1的子字符串
    }
cor++;
}
return NULL;
}
int main()
{
char arr1[]="abbbcdef";
char arr2[]="bbc";
char* ret=my_strstr(arr1,arr2);
if(ret==NULL)
{
    printf("字符串不存在\n");
}
else
{
    printf("%s\n",ret);
}
return 0;
}

        好了这一节我们就讲到这里,各位道友若有错请指教出来,在下务必接受,告辞!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值