宽字符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

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

wchar_t与char转换(总结)

#include//标准C++; string   tp; wchar_t   *s; char   *d; tp=s; d=tp.c_str(); 也可使用WideCharTo...

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

头文件:    typedef char str_ansi; typedef unsigned char ...

精选:深入理解 Docker 内部原理及网络配置

网络绝对是任何系统的核心,对于容器而言也是如此。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker的网络一直以来都比较薄弱,所以我们有必要深入了解Docker的网络知识,以满足更高的网络需求。

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

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

宽字符与窄字符的转换

最近在看opencv,无奈老外开发的东西TMD居然没有宽字符版本。 比如一个最简单的读取位图文件的Mat imread( const string& filename, int flags=1 );...

字符之殇——CHAR WCHAR

本文阐述了使用标准C库函数mbtowc进行多字节和宽字节转化的方法,以及一些诡异的转化错误的产生原因及解决方法。   一、ANSI编码简述 “ANSI编码”不同于ANSI(Ameri...

如何在Unicode与ANSI之间转换字符串

如何在Unicode与ANSI之间转换字符串? Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串;函数WideCharToMultiByte将宽字符串转换成等...

wchar与char字符转换的探究

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

C++ WINDOWS下 wchar_t *和char * 相互转化总结篇

说道wchar_t和char两个类型大家都不会陌生 wchar_t:在windows下是Unicode 16编码,也就是俗称宽字节 char:当然就是指一个字节,在windows下面默认是gbk编码的...

VS2012和2013里scanf_s无法输入字符串的解决方案

今天在VS2012里面使用scanf_s()函数时,发现它不能输入字符和字符串,为了验证是scanf_s的问题还是printf_s的问题,先直接输出字符,如下:int a1=1; float b1=1...

C++中char类型详解

#1char与字符的关系 ##1.1char类型到底代表什么 提到char类型,我相信学过C/C++的并不会陌生,char类型代表一个字节,在内存中有8位,所以signed char的范围为-...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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