宽字符wchar、窄字符char、无符号字符(unsigned char)之间的转换

原创 2016年08月30日 19:23:18


头文件:

  

 typedef char                                        str_ansi;
 typedef unsigned char                               str_utf8;
 typedef wchar_t                                     str_utf16;

class CAPECharacterHelper
{
public:
    static str_ansi * GetANSIFromUTF8(const str_utf8 * pUTF8);
    static str_ansi * GetANSIFromUTF16(const str_utf16 * pUTF16);
    static str_utf16 * GetUTF16FromANSI(const str_ansi * pANSI);
    static str_utf16 * GetUTF16FromUTF8(const str_utf8 * pUTF8);
    static str_utf8 * GetUTF8FromANSI(const str_ansi * pANSI);
    static str_utf8 * GetUTF8FromUTF16(const str_utf16 * pUTF16);
};

源文件:

 

str_ansi * CAPECharacterHelper::GetANSIFromUTF8(const str_utf8 * pUTF8)
{
    str_utf16 * pUTF16 = GetUTF16FromUTF8(pUTF8);
    str_ansi * pANSI = GetANSIFromUTF16(pUTF16);
    delete [] pUTF16;
    return pANSI;
}

str_ansi * CAPECharacterHelper::GetANSIFromUTF16(const str_utf16 * pUTF16)
{
    const int nCharacters = pUTF16 ? int(wcslen(pUTF16)) : 0;
    #ifdef _WIN32
        int nANSICharacters = (2 * nCharacters);
        str_ansi * pANSI = new str_ansi [nANSICharacters + 1];
        memset(pANSI, 0, (nANSICharacters + 1) * sizeof(str_ansi));
        if (pUTF16)
            WideCharToMultiByte(CP_ACP, 0, pUTF16, -1, pANSI, nANSICharacters, NULL, NULL);
    #else
        str_utf8 * pANSI = new str_utf8 [nCharacters + 1];
        for (int z = 0; z < nCharacters; z++)
            pANSI[z] = (pUTF16[z] >= 256) ? '?' : (str_utf8) pUTF16[z];
        pANSI[nCharacters] = 0;
    #endif

    return (str_ansi *) pANSI;
}

str_utf16 * CAPECharacterHelper::GetUTF16FromANSI(const str_ansi * pANSI)
{
    const int nCharacters = pANSI ? int(strlen(pANSI)) : 0;
    str_utf16 * pUTF16 = new str_utf16 [nCharacters + 1];

    #ifdef _WIN32
        memset(pUTF16, 0, sizeof(str_utf16) * (nCharacters + 1));
        if (pANSI)
            MultiByteToWideChar(CP_ACP, 0, pANSI, -1, pUTF16, nCharacters);
    #else
        for (int z = 0; z < nCharacters; z++)
            pUTF16[z] = (str_utf16) ((str_utf8) pANSI[z]);
        pUTF16[nCharacters] = 0;
    #endif

    return pUTF16;
}

str_utf16 * CAPECharacterHelper::GetUTF16FromUTF8(const str_utf8 * pUTF8)
{
    // get the length
    int nCharacters = 0; int nIndex = 0;
    while (pUTF8[nIndex] != 0)
    {
        if ((pUTF8[nIndex] & 0x80) == 0)
            nIndex += 1;
        else if ((pUTF8[nIndex] & 0xE0) == 0xE0)
            nIndex += 3;
        else
            nIndex += 2;

        nCharacters += 1;
    }

    // make a UTF-16 string
    str_utf16 * pUTF16 = new str_utf16 [nCharacters + 1];
    nIndex = 0; nCharacters = 0;
    while (pUTF8[nIndex] != 0)
    {
        if ((pUTF8[nIndex] & 0x80) == 0)
        {
            pUTF16[nCharacters] = pUTF8[nIndex];
            nIndex += 1;
        }
        else if ((pUTF8[nIndex] & 0xE0) == 0xE0)
        {
            pUTF16[nCharacters] = ((pUTF8[nIndex] & 0x1F) << 12) | ((pUTF8[nIndex + 1] & 0x3F) << 6) | (pUTF8[nIndex + 2] & 0x3F);
            nIndex += 3;
        }
        else
        {
            pUTF16[nCharacters] = ((pUTF8[nIndex] & 0x3F) << 6) | (pUTF8[nIndex + 1] & 0x3F);
            nIndex += 2;
        }

        nCharacters += 1;
    }
    pUTF16[nCharacters] = 0;

    return pUTF16; 
}

str_utf8 * CAPECharacterHelper::GetUTF8FromANSI(const str_ansi * pANSI)
{
    str_utf16 * pUTF16 = GetUTF16FromANSI(pANSI);
    str_utf8 * pUTF8 = GetUTF8FromUTF16(pUTF16);
    delete [] pUTF16;
    return pUTF8;
}

str_utf8 * CAPECharacterHelper::GetUTF8FromUTF16(const str_utf16 * pUTF16)
{
    // get the size(s)
    int nCharacters = int(wcslen(pUTF16));
    int nUTF8Bytes = 0;
    for (int z = 0; z < nCharacters; z++)
    {
        if (pUTF16[z] < 0x0080)
            nUTF8Bytes += 1;
        else if (pUTF16[z] < 0x0800)
            nUTF8Bytes += 2;
        else
            nUTF8Bytes += 3;
    }

    // allocate a UTF-8 string
    str_utf8 * pUTF8 = new str_utf8 [nUTF8Bytes + 1];

    // create the UTF-8 string
    int nUTF8Index = 0;
    for (int z = 0; z < nCharacters; z++)
    {
        if (pUTF16[z] < 0x0080)
        {
            pUTF8[nUTF8Index++] = (str_utf8) pUTF16[z];
        }
        else if (pUTF16[z] < 0x0800)
        {
            pUTF8[nUTF8Index++] = 0xC0 | (pUTF16[z] >> 6);
            pUTF8[nUTF8Index++] = 0x80 | (pUTF16[z] & 0x3F);
        }
        else
        {
            pUTF8[nUTF8Index++] = 0xE0 | (pUTF16[z] >> 12);
            pUTF8[nUTF8Index++] = 0x80 | ((pUTF16[z] >> 6) & 0x3F);
            pUTF8[nUTF8Index++] = 0x80 | (pUTF16[z] & 0x3F);
        }
    }
    pUTF8[nUTF8Index++] = 0;

    // return the UTF-8 string
    return pUTF8;
}

请注意,该转换函数中有开辟空间(new)而没有空间删除,在调用这些函数的时候注意在外面delete

相关文章推荐

VS中常见的宽字符和窄字符转换

VS常见的宽字符wchar和char之间的转换

宽字符wchar_t和窄字符char区别和相互转换

1.    首先,说下窄字符char了,大家都很清楚,就是8bit表示的byte,长度固定。char字符只能表示ASII码表中的256个字符,包括前128个可见字符和后面的128个不可见字符。    ...

UiAutoMator Helper自动运行测试用例

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi...

android UiAutomator一个完整的班级功能测试用例

本人在学习UiAutomator时候看了一些教程,写了一些用例的脚本,昨天终于写了一个相对完整的班级单元的用例,基本把所有功能点都覆盖到了,个人感觉算是一个完整的用例了,分享出来,如果不足,烦请指正。...

宽字符wchar_t和窄字符char区别和相互转换

宽字符wchar_t和窄字符char区别和相互转换 1.    首先,说下窄字符char了,大家都很清楚,就是8bit表示的byte,长度固定。char字符只能表示ASII码表中的256个字...

宽字符wchar_t和窄字符char区别和相互转换

转自:http://blog.csdn.net/nodeathphoenix/article/details/7416725 1.    首先,说下窄字符char了,大家都很清楚,就是8bi...

c++基本数据类型基本类型: 整型: 短整型: short int 整型: int 长整型:long int 字符型:char(分为有符号和无符号,默认有符号) 浮点型:

基本类型:   整型: 短整型: short int 整型: int 长整型:long int   字符型:char(分为有符号和无符号,默认有符号)   浮点型:单精度型:floa...

wchar与char字符转换的探究

本文主要通过实例测试了字符串和宽字符保存时的编码格式,以及对C标准的宽字符转换函数对于编码格式的转换进行了验证。...

C++宽字符:从char到wchar_t

从字符到整数 char是一种整数类型,这句话的含义是,char所能表示的字符在C/C++中都是整数类型。好,接下来,很多文章就会举出一个典型例子,比如,'a'的数值就是0x61。这种说法对吗?如...

彻底解密C++宽字符:1、从char到wchar_t

彻底解密C++宽字符:1、从char到wchar_t " href="http://www.163pan.com/files/c0x000k09.html" style="color:rgb(52,...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:宽字符wchar、窄字符char、无符号字符(unsigned char)之间的转换
举报原因:
原因补充:

(最多只允许输入30个字)