【C/C++】库函数中的字符串函数

本文详细介绍了C语言中常用的字符串操作函数,包括strcpy、strncpy、memcpy等,并提供了具体实现代码及注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

模拟库函数的中strcpy、strncpy、memcpy、memove、strcat、 strncat、 strcmp 、strncmp 、strstr、 strchr、 strlen、

直接贴代码,代码有注释

strcpy、strncpy
//des必须有足够的空间去容纳source,char[],
//des与source不能存在内存重叠、
//为什么返回char* ,为了实现链式表达式
char * my_strcpy(char * dst, const char * source)
{
    assert(dst != NULL && source != NULL);
    char* res = dst;
    while ((*dst++ = *source++) != '\0')
        ;
    return res;
}

//函数并没有为dst添加\0;src个数小于num个,那么提前结束
//count的值必须小于dst的长度
char * my_strncpy(char * dst, const char * src, size_t count)
{

    assert(dst != NULL && src != NULL);
    char *tmp = dst;
    //先把\0复制过去,count没有--
    while (count && (*tmp++ = *src++) != '\0')
        --count;
    //所以count要先减1
    if (count)
    {
        while (--count)
            *tmp++ = '\0';
    }
    return dst;
}

memcpy memove

//内存拷贝,没有考虑内存重叠的问题
void * my_memcpy(void * dst,const void * src, size_t count)
{

    assert(dst != NULL && src != NULL);
    void * ret = dst;
    while (count--) {
        *(char *)dst = *(char *)src;
        dst = (char *)dst + 1;
        src = (char *)src + 1;
    }

    return(ret);
}

//
void *  my_memmove(void * dst, const void * src, size_t count)
{
    assert(dst != NULL && src != NULL);
    void *res = dst;

    if (dst <= src || (char *)dst >= ((char *)src + count)) 
    {
        // Non-Overlapping Buffers
        while (count--)
        {
            *(char *)dst = *(char *)src;
            dst = (char *)dst + 1;
            src = (char *)src + 1;
        }
    }
    else 
    {
        //Overlapping Buffers
        //从后往前拷贝
        dst = (char *)dst + count - 1;
        src = (char *)src + count - 1;

        while (count--) 
        {
            *(char *)dst = *(char *)src;
            dst = (char *)dst - 1;
            src = (char *)src - 1;
        }
    }
    return(res);
}

strcat strncat

char * my_strcat(char * dst,const char * src)
{
    assert(dst != NULL && src != NULL);

    char * cp = dst;

    while (*cp != '\0')
        cp++;                   

    while (*cp++ = *src++);       

    return(dst);
}

char * my_strncat(char * front,const char * back, size_t count)
{
    assert(front != NULL && back != NULL);

    char *start = front;
    //找到front的结尾
    //while (*front != '\0')
    //      front++;

    while (*front++)
        ;
    front--;//front 在'\0'后面

    while (count--)
    if (!(*front++ = *back++))//等于'\0'执行return
        return(start);

    *front = '\0';
    return(start);
}

* strcmp strncmp *

int my_strcmp(const char * src,const char * dst)
{
    int ret = 0;

    while (!(ret = *(unsigned char *)src - *(unsigned char *)dst) && *dst)
        ++src, ++dst;
    //注意上面src后面是逗号
    if (ret < 0)
        ret = -1;
    else if (ret > 0)
        ret = 1;

    return(ret);
}


//这是库函数中实现的strncmp函数,它以四个字节划分,可能是为了效率问题吧。
int  my_strncmp1(const char *first,const char *last,size_t count)
{
    assert(first != NULL && last != NULL);
    size_t x = 0;

    if (!count)
    {
        return 0;
    }

    /*
    * This explicit guard needed to deal correctly with boundary
    * cases: strings shorter than 4 bytes and strings longer than
    * UINT_MAX-4 bytes .
    */
    if (count >= 4)
    {
        /* unroll by four */
        for (; x < count - 4; x += 4)
        {
            first += 4;
            last += 4;

            if (*(first - 4) == 0 || *(first - 4) != *(last - 4))
            {
                return(*(unsigned char *)(first - 4) - *(unsigned char *)(last - 4));
            }

            if (*(first - 3) == 0 || *(first - 3) != *(last - 3))
            {
                return(*(unsigned char *)(first - 3) - *(unsigned char *)(last - 3));
            }

            if (*(first - 2) == 0 || *(first - 2) != *(last - 2))
            {
                return(*(unsigned char *)(first - 2) - *(unsigned char *)(last - 2));
            }

            if (*(first - 1) == 0 || *(first - 1) != *(last - 1))
            {
                return(*(unsigned char *)(first - 1) - *(unsigned char *)(last - 1));
            }
        }
    }

    /* residual loop */
    for (; x < count; x++)
    {
        if (*first == 0 || *first != *last)
        {
            return(*(unsigned char *)first - *(unsigned char *)last);
        }
        first += 1;
        last += 1;
    }

    return 0;
}

int  my_strncmp2(const char *first, const char *last, size_t count)
{
    assert(first);
    assert(last);
    if (count == 0)
        return 0;
    while (count)
    {
        if (*first == '0' || *first != *last)
            return *first - *last;
        first++;
        last++;
        count--;
    }
    return 0;
}

* strstr strchr*

char * my_strstr(const char * str1,const char * str2)
{
    assert(str1); assert(str2);
    char *cp = (char *)str1;
    char *s1, *s2;

    if (!*str2)
        return((char *)str1);

    while (*cp)
    {
        s1 = cp;
        s2 = (char *)str2;

        while (*s1 && *s2 && !(*s1 - *s2))
            s1++, s2++;

        if (!*s2)
            return(cp);

        cp++;
    }

    return(NULL);

}

char *  my_strchr(const char * string,int ch)
{
    while (*string && *string != (char)ch)
        string++;

    if (*string == (char)ch)
        return((char *)string);
    return(NULL);
}

strlen

size_t  my_strlen(const char * str)
{
    const char *eos = str;

    while (*eos++ != '\0')
        ;
    //此时eos的位置在\0后面
    return(eos - str - 1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值