C/C++共通文字列ライブラリ関数の実装

8967 ワード

cのstring.hヘッダファイルには文字列を操作する関数が多く存在し,これらの関数を用いて文字列を容易に操作することができる.一般的な文字列関数について説明し、実装します.
strcpy関数プロトタイプ:char*strcpy(char*dest,char*src)関数機能:strが指すnullptrの文字列をdstが指す配列にコピーし、destのポインタを返します.関数の説明:srcとdestが指すメモリ領域が重複せず、destがsrcの文字列を収容するのに十分な空間が必要であることを保証します.関数の実装
char* _strcpy(char* dest, const char* src)
{
    assert(dest != nullptr&&src != nullptr);
    //  dest   src      ,       
    char* tmp = dest;
    while (*tmp++ = *src++)
        ;
    return dest;
}

strncpy
関数プロトタイプ:char*strncpy(char*dest,const char*src,size_t n)関数機能:srcが指すnullptrで終わる文字列の前のnバイトをdestが指す配列にコピーします.関数の説明:srcの最初のnバイトにnullptrが含まれていない場合、結果はnullptrで終了しません.srcの長さがnバイト未満の場合、nullptrでdestをnバイトがコピーされるまで埋め込む.srcとdestが指すメモリ領域が重ならず、destがsrcの文字列を収容するのに十分な空間が必要であることを保証します.関数の実装:
char* _strncpy(char* dest, const char* src, int n)
{
    assert(dest != nullptr&&src != nullptr);
    //  dest   src      ,       
    int i = 0;
    char* tmp = dest;
    while (i++ < n && (*tmp++ = *src++))
        ;
    while (i++ < n)
        *tmp++ = '\0';
    return dest;
}

strcat関数プロトタイプ:char*strcat(char*dest,const char*src)関数機能:srcが指す文字列をdestの末尾(destの末尾を覆う'0')に追加し、'0'を追加します.関数の説明:srcとdestが指すメモリ領域が重複せず、destがsrcの文字列を収容するのに十分な空間が必要であることを保証します.関数の実装:
char* _strcat(char* dest, const char* src)
{
    assert(dest != nullptr&&src != nullptr);
    //  dest   src      ,       
    char* tmp = dest;
    while (*tmp)//  while(*dest++)    dest  '\0'      
        tmp++;
    while (*tmp++ = *src++)
        ;
    return dest;
}

注意:使用時に実パラメータdestがchar*dest=「abcd」として作成されると、コンパイルは可能ですが、実行時に中断が発生します.abcdは文字列定数であり、変更はできません.char dest[n]=「abcd」を使用して作成できます.
strncat関数プロトタイプ:char*strncat(char*dest,const char*src,size_t n)関数機能:srcが指す文字列の最初のn文字をdestの最後に追加し(destの最後の'0'を上書き)、'0'を追加します.関数の説明:srcとdestが指すメモリ領域が重複せず、destがsrcの文字列を収容するのに十分な空間が必要であることを保証します.関数の実装:
char* _strncat(char* dest, const char* src, size_t n)
{
    assert(dest != nullptr&&src != nullptr);
    //  dest   src      ,       
    char* tmp = dest;
    while (*tmp)//  while(*dest++)    dest  '\0'      
        tmp++;

    while (n--)
    {
        if (!(*tmp++ = *src++))//   src     n ,  tmp  '\0'
            return dest;
    }

    *tmp = '\0';//  src    n ,       
    return dest;
}

strlen関数プロトタイプ:size_t _strlen(const char*str)関数機能:文字列strの長さを計算します.関数の説明:終了文字NULLを含まないsの長さを返します.関数の実装:
//    
size_t _strlen(const char* str)
{
    assert(str);
    const char* eofStr = str;
    while (*eofStr++)
        ;
    return (eofStr - str - 1);
}
//    ,     (     )
size_t _strlen_R(const char* str)
{
    /*if ('\0' == str)
        return 0;

    return _strlen_R(str + 1) + 1;*/

    return *str ? _strlen_R(str + 1) + 1 : 0;//    
}

strcmp関数プロトタイプ:int_strcmp(const char*dest,const char*src)関数機能:文字列destとsrcを比較します.関数の説明:destsrcの場合、戻り値>0関数が実現されます.
int _strcmp(const char* dest, const char* src)
{
    assert(dest != nullptr&&src != nullptr);
    //  dest   src      ,       
    while (*dest&&*src && (*dest == *src))
    {
        dest++;
        src++;
    }
    return (*dest - *src);
}

strncmp関数プロトタイプ:int_strncmp(const char*dest,const char*src,size_t n)関数機能:文字列destとsrcの最初のn文字を比較します.関数の説明:前のnバイトが完全に等しい場合、戻り値は0です.前のnバイトの比較中にdest[n]とsrc[n]が等しくない場合、(dest[n]-src[n])が返されます.関数の実装:
int _strncmp(const char* dest, const char* src, size_t n)
{
    assert(dest != nullptr&&src != nullptr);
    //  dest   src      ,       
    if (!n)// n 0,   0;
        return 0;
    while (n--&&*dest&&*src && (*dest == *src))
    {
        dest++;
        src++;
    }

    return (*dest - *src);
}

strstr関数プロトタイプ:関数機能:dest文字列でsrc文字列が初めて現れる位置(srcの'0'を含まない)を特定します.関数の説明:見つからない場合は、空のポインタを返します.関数の実装:
char* _strstr(const char* dest, const char* src)
{
    assert(dest != nullptr);
    //  dest      ,       
    if (!src)
        return (char*)dest;

    while (*dest)
    {
        const char* destTmp = dest;
        const char* srcTmp = src;
        while (*srcTmp == *destTmp && (*srcTmp))//  *srcTmp *destTmp      '\0'         
        {
            srcTmp++;
            destTmp++;
        }
        if (!(*srcTmp))
            return (char*)destTmp;

        dest++;
    }
    return nullptr;
}

間違いがあれば指摘してください.ありがとうございます.