C标准库函数实现之字符串操作

        在C/C++开发工作中会经常遇到操作字符串的情形,只有在了解了其实现方式,运用时才能随心所欲,有的放矢。

        小编结合工作中操作字符串的经验,整理了一些常用的字符串操作函数予以分享。

        持续更新中......


一、前期准备

/* 基本类型定义 */

typedef signed int        Gint32;        /**< -2147483648 ~ 2147483647             */
typedef unsigned int    Guint32;    /**< 0 ~ 4294967295(0xffffffff)           */
typedef signed short    Gint16;        /**< -32768 ~ 32767                       */
typedef unsigned short    Guint16;    /**< 0 ~ 65535(0xffff)                    */
typedef signed char        Gint8;        /**< -128 ~ 127                           */
typedef unsigned char    Guint8;        /**< 0 ~ 255(0xff)                        */
typedef float            Gfloat32;    /**< -3.40E+38 ~ +3.40E+38 精度为6~7位    */
typedef double            Gfloat64;    /**< -1.79E+308 ~ +1.79E+308 精度为15~16位*/

#if defined(PLATFORM_ANDROID) || defined(PLATFORM_MAC) || defined(PLATFORM_TIZEN) || defined(PLATFORM_UBUNTU)
    typedef long long            Gint64;        /**< -9223372036854775808i64 ~ 9223372036854775807i64 */
    typedef unsigned long long    Guint64;    /**< 0 ~ 18,446,744,073,709,551,615(0xffffffffffffffffui64) */
#else
    typedef __int64                Gint64;        /**< -9223372036854775808i64 ~ 9223372036854775807i64 */
    typedef unsigned __int64    Guint64;    /**< 0 ~ 18,446,744,073,709,551,615(0xffffffffffffffffui64) */

#endif


/**
* Gtrue/Gfalse枚举类型
*
*/
typedef enum {
    Gfalse = 0,
    Gtrue  = 1
} Gbool;

#if (defined PLATFORM_WIN32) || (defined PLATFORM_WINCE)
    typedef Guint16        Gchar;
#else
    typedef Guint32        Gchar;
#endif


二、字符串操作

1)窄字符转换为宽字符

Gbool Gmbtowc(Gchar *pwc, const Guint8 *s, Gint32 n)
{
    const Guint8 *ps = s;
    Guint8 c1, c2;
    Gbool bRet = Gfalse;

    if (n >= 2)
    {
        c1 = s[0];
        c2 = s[1];
        if ((0x80u <= c1) && (0x40u <= c2))
        {
            *pwc = gbk_2_unicode[(((Gint32)c1-0x80) * ((0xFF - 0x40) + 1)) + ((Gint32)c2 - 0x40)]; //gbk_2_unicode参照 字符GBK与UNICODE静态对照表
            bRet =  Gtrue;
        }
    }

    return bRet;
}

2)宽字符转换为窄字符
Gbool Gwctomb(Guint8 *r, const Gchar wc, Gint32 n)
{
    Gbool bRet = Gfalse;

    if (n >= 2)
    {
        Guint8 c1, c2;
        Gint32 offset = -1;

        c1 = (Guint8)(wc & 0x00ffu);
        c2 = wc >> 8;
        if (c2 <= 0x04u)
        {
            offset = ((Gint32)c2 * 256) + (Gint32)c1;
        }
        else if ((0x20u <= c2) && (c2 <= 0x26u))
        {
            offset = (((Gint32)c2-0x20) * 256) + (Gint32)c1 + (((0x04 - 0x00) + 1) * 256);
        }
        else if ((0x30u <= c2) && (c2 <= 0x33u))
        {
            offset = (((Gint32)c2-0x30) * 256) + (Gint32)c1 + (((0x26 - 0x20) + 1) * 256) + (((0x04 - 0x00) + 1) * 256);
        }
        else if ((0x4eu <= c2) && (c2 <= 0x9fu))
        {
            offset = (((Gint32)c2-0x4e) * 256) + (Gint32)c1 + (((0x33 - 0x30) + 1) * 256) + (((0x26 - 0x20) + 1) * 256) + (((0x04 - 0x00) + 1) * 256);
        }
        else if ((0xe0u <= c2) && (c2 <= 0xe8u))
        {
            offset = (((Gint32)c2-0xe0) * 256) + (Gint32)c1 + (((0x9f - 0x4e) + 1) * 256) + (((0x33 - 0x30) + 1) * 256) + (((0x26 - 0x20) + 1) * 256) + (((0x04 - 0x00) + 1) * 256);
        }
        else if (0xf9u <= c2)
        {
            offset = (((Gint32)c2 - 0xf9) * 256) + (Gint32)c1 + (((0xe8 - 0xe0) + 1) * 256) + (((0x9f - 0x4e) + 1) * 256) + (((0x33 - 0x30) + 1) * 256) + (((0x26 - 0x20) + 1) * 256)+ (((0x04 - 0x00) + 1) * 256);
        }
        else
        {
            offset = -1;
        }

        if (offset != -1)
        {
            Guint32 uTemp;
            offset = (Gint32)unicode_2_gbk[offset]; //unicode_2_gbk参照字符GBK与UNICODE静态对照表
            uTemp = (Guint32)offset & 0x00ffu;
            r[0] = (Guint8)uTemp;
            uTemp = (Guint32)offset >> 8u;
            r[1] = (Guint8)uTemp;

            bRet = Gtrue;
        }
    }

    return bRet;
}

3)窄字符串转换为宽字符串

Gint32 Gmbstowcs(Gchar *wcstr, Guint32 sizeInWords, const Guint8 *mbstr)
{
    const Guint8 *ps;
    Gchar *pw;
    Gint32 nRet = 0;

    if ((wcstr == GNULL) || (mbstr == GNULL) || (sizeInWords < 1u))
    {
        nRet = 0;
    }
    else
    {
        ps = mbstr;
        pw = wcstr;
        sizeInWords--;    /* for the terminating null */
        while ((*ps != 0) && (sizeInWords > 0u))
        {
            if (*ps <= 0x7F)
            {
                *pw = *ps;
                pw++;
                ps++;
            }
            else
            {
                if (Gtrue == Gmbtowc(pw, ps, 2))
                {
                    ps += 2;
                    pw++;
                }
                else
                {
                    break;
                }
            }
            sizeInWords--;
        }
        *pw = 0;

        nRet = (pw - wcstr) * sizeof(Gchar);
    }

    return nRet;
}

4)宽字符串转换为窄字符串
Gint32 Gwcstombs(Guint8 *mbstr, Guint32 sizeInBytes, const Gchar *wcstr)
{
    Guint8  *ps;
    const Gchar *pw;
    Gint32 nRet = 0;

    if ((wcstr == GNULL) || (mbstr == GNULL) || (sizeInBytes < 1u))
    {
        nRet = 0;
    }
    else
    {
        ps = mbstr;
        pw = wcstr;
        sizeInBytes--;
        while ((*pw != 0) && (sizeInBytes > 0u))
        {
            if (*pw <= 0x7F)
            {
                *ps = (Guint8)*pw;
                pw++;
                ps++;
                sizeInBytes--;
            }
            else
            {
                if (Gtrue == Gwctomb(ps, *pw, 2))
                {
                    ps += 2;
                    pw++;
                    sizeInBytes -= 2u;
                }
                else
                {
                    break;
                }
            }
        }
        *ps = 0;

        nRet = ps - mbstr;
    }

    return nRet;
}

5)宽字符--->宽字符拷贝

Gchar* Gstrcpy(Gchar* strDest, const Gchar* strSource)
{
    Gchar *p = GNULL;
    if ((strDest != GNULL) && (strSource != GNULL))
    {
        p = strDest;
        while( *p++ = *strSource++ );               /* Copy src over dst */
    }
    return strDest;
}

6)窄字符串--->窄字符串拷贝
Gint8* GstrcpyA(Gint8* strDest, const Gint8* strSource)
{
    Gint8 *p = GNULL;
    if ((strDest != GNULL) && (strSource != GNULL))
    {
        p = strDest;
        while( *p++ = *strSource++ );               /* Copy src over dst */
    }
    return strDest;
}

7)窄字符串--->宽字符串拷贝

Gchar* GstrcpyGA(Gchar* strDest, const Gint8* strSource)
{
    Gchar szTmp[GMAX_PATH];

    Gmbstowcs(szTmp, (Guint32)GMAX_PATH, strSource);

    return Gstrcpy(strDest, szTmp);
}

8)宽字符串--->窄字符串拷贝

Gint8* GstrcpyAG(Gint8* strDest, const Gchar* strSource)
{
    Gint8 szTmp[GMAX_PATH];

    (void)Gwcstombs(szTmp, (Guint32)GMAX_PATH, strSource);

    return GstrcpyA(strDest, szTmp);
}

9)宽字符串<--->宽字符串比较

Gint32 Gstrcmp(const Gchar* strSource, const Gchar* strDest)
{
    Gint32 ret = 0;

    while( ! (ret = (Gint32)(*strSource - *strDest)) && *strDest)
    {
        ++strSource;
        ++strDest;
    }

    if ( ret < 0 )
        ret = -1;
    else if ( ret > 0 )
        ret = 1;

    return ret;
}

10)窄字符串<--->窄字符串比较
Gint32 GstrcmpA(const Gint8* strSource, const Gint8* strDest)
{
    Gint32 ret = 0;

    while( ! (ret = (Gint32)(*strSource - *strDest)) && *strDest)
    {
        ++strSource;
        ++strDest;
    }

    if ( ret < 0 )
        ret = -1;
    else if ( ret > 0 )
        ret = 1;

    return ret;
}

11)宽字符串<--->宽字符串链接
Gchar* Gstrcat(Gchar* strDest, Gchar* strSource)
{
    Gchar *p1 = GNULL, *p2 = GNULL;
    
    if ((strDest != GNULL) && (strSource != GNULL))
    {
        p1 = strDest;
        while (*p1 != 0)
        {
            p1++;
        }

        p2 = strSource;
        while (*p2 != 0)
        {
            *p1 = *p2;
            p1++;
            p2++;
        }
        *p1 = *p2;
    }
    return strDest;
}

12)窄字符串<--->窄字符串链接
Gint8* GstrcatA(Gint8* strDest, Gint8* strSource)
{
    Gint8 *p1 = GNULL, *p2 = GNULL;
    
    if ((strDest != GNULL) && (strSource != GNULL))
    {
        p1 = strDest;
        while (*p1 != 0)
        {
            p1++;
        }

        p2 = strSource;
        while (*p2 != 0)
        {
            *p1 = *p2;
            p1++;
            p2++;
        }
        *p1 = *p2;
    }
    return strDest;
}

13)正向查找字符串是否存在某字符

Gchar* Gstrchr(Gchar *str, Gchar ch)
{
    Gchar *p = GNULL;
    Gint32 i, len;

    if (GNULL != str)
    {
        len = Gstrlen(str);
        for (i = 0; i < len; i++)
        {
            if (str[i] == ch)
            {
                p = &str[i];
                break;
            }
        }
    }

    return p;
}

14)逆向查找字符串是否存在某字符

Gchar* Gstrrchr(Gchar *str, Gchar ch)
{
    Gchar *p = GNULL;
    Gint32 i, len;

    if (GNULL != str)
    {
        len = Gstrlen(str);
        for (i = len-1; i >= 0; i--)
        {
            if (str[i] == ch)
            {
                p = &str[i];
                break;
            }
        }
    }

    return p;
}

15)获取窄字符串长度
Gint32 GstrlenA(const Gint8* str)
{
    const Gint8 *p = str;
    Gint32 nRet = 0;

    if (p != GNULL)
    {
        while( *p++ );
        nRet = p - str - 1;
    }

    return nRet;
}

16)获取宽字符串长度
Gint32 Gstrlen(const Gchar* str)
{
    const Gchar *p = str;
    Gint32 nRet = 0;

    if (p != GNULL)
    {
        while( *p++ );
        nRet = p - str - 1;
    }

    return nRet;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值