模拟实现c库函数strcpy,strcat,strstr,strcmp,memcpy,memmove

目录

strcpy

strcpy是字符串复制函数,把从src(源字符串指针)地址开始且含有’\0’结束符的字符串复制到以dst(目的字符串指针)开始的地址空间。
注意:在进行复制时是连字符串结束标识符‘\0’一并复制。
只能拷贝字符串

char * My_strcpy(char* dst, const char* src)
{

    char * start = dst;
    assert(dst&&src);
    while (*dst = *src)
    {
        dst++;
        src++;
    }

    return start;
}

int main()
{
    char arr1[] = "hello";
    char arr2[] = "world";
    My_strcpy(arr1, arr2);
    printf("%s\n", arr1);
    system("pause");
    return 0;
}

strcat

strcat是用于字符串连接的函数,会将参数 src 字符串复制到参数 dst 所指的字符串尾部;dst 最后的结束字符 NULL 会被覆盖掉,并在连接后的字符串的尾部再增加一个 NULL。
注意:dst 与 src 所指的内存空间是不能重叠的,并且dst 要有足够的空间来容纳要复制的字符串。

char* My_strcat(char* dst, const char* src)
{
    char* start = dst;
    assert(dst&&src);

    while (*dst)
    {
        dst++;
    }
    while (*dst = *src)
    {
        dst++;
        src++;
    }
    return start;

}

int main()
{
    char arr1[] = "hello";
    char arr2[] = "world";
    My_strcat(arr1, arr2);
    printf("%s\n", arr1);
    system("pause");
    return 0;
}

strstr

strstr是从字符串str1中查找是否有字符串str2函数。如果str2是str1的子串,确定子串在str1中第一次出现的位置,返回这个位置的地址。如果不是子串,返回NULL。

char* My_strstr(char*dst,char*src)
{
    char *ptr = dst;
    assert(dst&&src);
    while(*ptr)
    {
        char*p1 = ptr;
        char*p2 = src;
        while ((*p1) && (*p2) && (*p1 == *p2))
        {
            p1++;
            p2++;

        }
        if (*p2 == '\0')
        {
            return (char*)ptr;
        }
        ptr++;
    }
    return NULL;
}

int main()
{
    char arr1[] = "hello world";
    char arr2[] = "world";
    char* ret = My_strstr(arr1,arr2);
    if (ret == NULL)
    {
        printf("没有\n");
    }
    else
    {
        printf("%s\n", ret);
    }
    system("pause");
    return 0;
}

strcmp

strcmp用于比较两个字符串s1和s2,若s1>s2, 返回1; s1 == s2, 返回0;

char* My_strcmp(const char*s1, const char*s2)
{
    assert(s1&&s2);
    while ((*s1==*s2))
    {
        if (*s1 == '\0')
        {
            return 0;
        }
        s1++;
        s2++;
    }
    if (*s1 > *s2)
    {
        return -1;
    }
    else
    {
        return 1;
    }
}

int main()
{
    char arr1[] = "hello world";
    char arr2[] = "world";
    int ret = My_strcmp(arr1, arr2);
    printf("%d\n", ret);
    system("pause");
    return 0;
}

memcpy

注意!使用memcpy时要保证源和目标的内存区域不能重叠。
功能 c和c++使用的内存拷贝函数.从源s所指的内存地址的起始位置开始拷贝n个字节到目标str所指的内存地址的起始位置中
memcpy与strcpy有以下不同:
1.复制内容不同。strcpy复制字符串,而memcpy复制字符数组、整型、结构体、类等。
2.复制方法不同。strcpy遇到被复制字符串的’\0’结束(有可能会溢出),memcpy由第三个参数决定复制的长度。

void* My_memcpy(void* dst, void* src, size_t n)
{
    void* start = dst;
    while (n--)
    {
        *(char*)dst = *(char*)src;
        dst = (char*)dst + 1;
        src = (char*)src + 1;
    }
    return start;
}

int main()
{
    char arr1[] = "hello";
    char arr2[] = "hi";
    My_memcpy(arr1, arr2, 5);
    printf("%s\n", arr1);
    system("pause");
    return 0;
}

memmove

memmove用于从src拷贝count个字节到dst,如果目标区域和源区域有重叠的话,
memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。
但复制后src内容会被更改。但是当目标区域与源区域没有重叠则和memcpy函数功能相同。

void* My_memmove(void* dst, const void* src, size_t n)
{
    char* pdst =(char*) dst;
    char* psrc = (char*)src;
    assert(dst&&src);
    if (pdst <= psrc&& pdst >= psrc + n)//正常情况下从前到后拷贝;
    {
        while (n--)
        {
            *pdst = *psrc;
        }
    }
    else//出现内存覆盖时从后向前拷贝;
    {
        while (n--)
        {
            *(pdst + n) = *(psrc + n);
        }
    }
    return dst;
}

int main()
{
    char arr1[] = "abcdefg";
    char arr2[] = "hijklmn";
    char arr3[10] = { 0 };
    My_memmove(arr3, arr1, 7);
    My_memmove(arr1+2, arr1, 3);
    printf("正常情况:%s\n", arr3);
    printf("内存覆盖情况下:%s\n", arr1);
    system("pause");
    return 0;
}

如有错误希望大家指正^v^

猜你喜欢

转载自blog.csdn.net/important_/article/details/79207050