天天看點

C語言:模拟實作strlen、strcpy、strcat、strstr、strcmp函數

當我們在學習字元串的時候,經常會使用到strlen、strcpy、strcat、strstr、strcmp這幾個庫函數,但今天我們就用代碼來自己實作my_strlen、my_strcpy、my_strcat、my_strstr、my_strcmp這幾個函數。

strlen

功能:計算字元串長度(不計算’\0’)

傳回值類型:int

實作my_strlen有三種方式:

1.計數法

思路:顧名思義,就是從前往後一個一個數

int my_strlen(const char *str)
    {
        int count = ;
        assert(str);//斷言str有效
        while (*str++)
        {
            count++;
        }
        return count;
    }
    int main()
    {
        char arr[] = "abcdef";
        int ret = my_strlen(arr);
        printf("%d\n", ret);
        system("pause");
        return ;
    }
           

2.遞歸

這種方法不用建立臨時變量

int my_strlen(const char *str)
    {
        assert(str);
        if (*str == '\0')
            return ;
        else
            return  + my_strlen(++str);
    }
           

3.指針相減

思路:一個指針指向首位址,另一個指針指向’\0’

int my_strlen(char *str)
    {
        char *ret = str;
        assert(str);
        while (*ret != '\0')
        {
            ret++;
        }
        return ret - str;
    }
           

結果:6

strcpy

功能:strcpy( char *dest, const char *str ) 将str所指字元串拷貝到dest所指的字元串中,并且dest和str所指的記憶體不能重 疊,這就要求dest要有足夠的空間來存儲str所指的内容。

傳回值類型:char* (為了實作鍊式通路)

思路:将str所指内容按順序逐一拷貝到dest所指的字元串中

char* my_strcpy(char *dest, const char *str)
    {
        char *ret = dest;
        assert(dest && str);
        while (*dest++ = *str++)
        {
            ;
        }
        return ret;
    }

    int main()
    {
        char arr1[] = {  };
        char arr2[] = "abcdef";
        char *ret = my_strcpy(arr1, arr2);
        printf("%s\n", ret);
        system("pause");
        return ;
    }
           

結果:abcdef

strcat

功能:strcpy( char *dest, const char *str ) 将str所指向的字元串複制到dest所指向的字元串的後面(覆寫掉原來dest所指向字元串的’\0’)

傳回值類型:char*

思路:先找到dest所指向字元串的’\0’,然後開始複制str所指向字元串的内容(注:要将str所指向字元串的’\0’頁複制)

char* my_strcpy(char *dest, char *str)
    {
        char *ret = dest;
        assert(dest && str);
        while (*dest)
        {
            dest++;
        }
        while (*dest++ = *str++)
        {
            ;
        }
        return ret;
    }

    int main()
    {
        char arr1[] = "abcdef";
        char arr2[] = "ghijk";
        char *ret = my_strcpy(arr1, arr2);
        printf("%s\n", ret);
        system("pause");
        return ;
    }
           

結果:abcdefghijk

strstr

功能:strstr( const char *str1, const char *str2 ) 查找str2所指向的字元串是否是str1所指向字元串的子串,則傳回str2在str1的首次出現的位址,若不是,則傳回NULL

傳回值類型:char *

思路:對str1所指向的字元串進行周遊,看是否包含str2所指向的字元串

char* my_strstr(char *str1, char *str2)
    {
        assert(str1 && str2);
        char *start = str1;
        char *cur = str2;
        char *s1 = NULL;
        if (*str2 == '\0')
        {
            return NULL;
        }
        else
        {
            while (*start)
            {
                s1 = start;
                cur = str2;
                while (*s1 && *cur && (*s1 == *cur))
                {
                    s1++;
                    cur++;
                }
                if (*cur == '\0')
                {
                    return start;
                }
                start++;
            }
        }
    }

    int main()
    {
        char arr1[] = "abbcdefg";
        char arr2[] = "bcd";
        char *ret = my_strstr(arr1, arr2);
        if (*ret)
        {
            printf("%s\n", ret);
        }
        else
        {
            printf("找不到\n");
        }
        system("pause");
        return ;
    }
           

結果:bcdefg

strcmp

功能:strcmp( const char *str1, const char *str2 ) 比較兩個字元串的大小

傳回值類型:int 若為0,兩個字元串相等;若為1,第一個字元串大;若為-1,第一個字元串小

思想:将兩個字元串對應位置進行相減(第一個減去第二個)

int my_atrcmp(const char str1[], const char str2[])
    {
        assert(str1 && str2);
        int ret = ;
        while ( !(ret = *(unsigned char *)str1 - *(unsigned char *)str2) && *str1 )
        {
            str1++;
            str2++;
        }
        if (ret < )
            return -;
        else if (ret > )
            return ;
        else
            return ;
    }

    int main()
    {
        char arr1[] = "abcdef";
        char arr2[] = "abcdef";
        int ret = my_atrcmp(arr1, arr2);
        if ( == ret)
        {
            printf("相等\n");
        }
        else if (- == ret)
        {
            printf("第一個小\n");
        }
        else
        {
            printf("第一個大\n");
        }
        system("pause");
        return ;
    }
           

結果:相等

總結:strcpy、strstr、strcat這三個函數在使用的時候,都需要記錄首個字元的位址,都是通過’\0’來作為結束條件,傳回值都是char *,而strlen、strcmp傳回值都是整形。

繼續閱讀