在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)窄字符转换为宽字符
{
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;
}
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;
}