字符串库函数的模拟实现以及用法

//strlen

字符串已经 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )。

参数指向的字符串必须要以 '\0' 结束。

注意函数的返回值为size_t,是无符号的( 易错 )

size_t My_strenl(const char* p1)
{
    if (*p1 == '\0')
        return 0;
    int count = 0;
    while (*p1 != '\0')
    {
        *(p1++);
        ++count;
    }

    return count;
}


//strcpy

源字符串必须以 '\0' 结束。

会将源字符串中的 '\0' 拷贝到目标空间。

目标空间必须足够大,以确保能存放源字符串。

目标空间必须可变。


 

char* My_strcpy(char* strDestination, const char* strSource)
{
    //排除指针不能为空
    assert(strDestination!= NULL && strSource!= NULL);

    //保护数据
    char* Dest = strDestination;
    const char* Sou = strSource;

    //拷贝

    while (*Sou != '\0')
    {
        *Dest++ = *Sou++;
    }
    *Dest = *Sou;
    return strDestination;
}


//strcmp

第一个字符串大于第二个字符串,则返回大于0的数字

第一个字符串等于第二个字符串,则返回0

第一个字符串小于第二个字符串,则返回小于0的数字


int My_strcmp(const char* string1, const char* string2)
{
    //排除指针不能为空
    assert(string1 != NULL && string2 != NULL);
    //比较大小
    while (*string1!='\0' && *string2!='\0')
    {
        if (*string1 - *string2 != 0)
            break;
        string1++;
        string2++;
    }
    return *string1 - *string2;

}

//strcat

源字符串必须以 '\0' 结束。

目标空间必须有足够的大,能容纳下源字符串的内容。

目标空间必须可修改。

char* My_strcat(char* strDestination, const char* strSource)
{
    //检查数据是否为空
    assert(*strDestination != '\0' && *strSource != '\0');
    //保护数据
    char* Dest =strDestination;
    const char* Sou =strSource;
    //进行链接
    while (*Dest != '\0')
    {
        Dest++;
    }
    while (*Sou != '\0')
    {
        *Dest++ = *Sou++;
    }
    *Dest = *Sou;
    return strDestination;
}

//strstr

char* my_strstr(const char* p1, const char* p2)
{
    assert(p1 != NULL);
    assert(p2 != NULL);
    char* s1 = NULL;
    char* s2 = NULL;
    char* cur = (char*)p1;
    if (*p2 == '\0')
    {
        return (char*)p1;                   
    }

    while (*cur)
    {
        s1 = cur;                      
        s2 = (char*)p2;                    
        while ((*s1 != 0) && (*s2 != 0) && *s1 == *s2)           
        {                                           
            s1++;                                    
            s2++;
        }
        if (*s2 == '\0')             
        {                             
            return (char*)cur;
        }
        if (*s1 == '\0')
        {
            return NULL;           
        }
        cur++;
    }

    return NULL;

}


//memcpy

函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。

这个函数在遇到 '\0' 的时候并不会停下来。

如果source和destination有任何的重叠,复制的结果都是未定义的。
 

void* My_memcpy(void* dest, const void* src, size_t count)
{
    void* ret = dest;
    assert(dest != NULL);
    assert(src!= NULL);

    while (count--)
    {
        *(char*)dest = *(char*) src;
        dest = (char*)dest + 1;
        src = (char*)src + 1;
    }
    return (ret);
}


//mommove   

和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。

如果源空间和目标空间出现重叠,就得使用mommove函数处理。

void* My_memmove(void* dest, const void* src, size_t count)
{
    void* ret = dest;
    if (dest <= src || (char*)dest >= ((char*)src + count))
    {
        while (count--)
        {
            *(char*)dest = *(char*)src;
            dest = (char*)dest + 1;
            src = (char*)src + 1;
        }
    }


    else
    {
        dest = (char*)dest + count - 1;
        src = (char*)src + count - 1;
        while (count--)
        {
            *(char*)dest = *(char*)src;
            dest = (char*)dest + 1;
            src = (char*)src + 1;
        }
    }
    return ret;
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值