模擬實現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^

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章