c++字符串编码格式转换

  • Post author:
  • Post category:其他


字符串转换函数介绍

// 函数功能:该函数映射一个字符串到一个 宽字节(unicode)的字符串。由该函数映射的字符串没必要是多字节字符组。
// 函数原型:
            int WINAPI MultiByteToWideChar(
                // 指定执行转换的 字符集,这个参数可以为系统已安装或有效的任何字符集所给定的值。
                _In_ UINT CodePage,

                // 一组位标记用以指出是否未转换成预作或 宽字符(若组合形式存在),是否使用象形文字替代 控制字符,以及如何处理无效字符。
                _In_ DWORD dwFlags,

                // 指向将被转换 字符串的字符。
                _In_NLS_string_(cbMultiByte) LPCCH lpMultiByteStr,

                // 指定由参数lpMultiByteStr指向的字符串中 字节的个数。如果lpMultiByteStr指定的字符串以空字符终止,可以设置为-1(如果字符串不是以空字符中止,设置为-1可能失败,可能成功),此参数设置为0函数将失败。
                _In_ int cbMultiByte, 

                // 指向接收被转换字符串的 缓冲区。
                _Out_writes_to_opt_(cchWideChar,return) LPWSTR lpWideCharStr,

                // 指定由参数lpWideCharStr指向的缓冲区的宽字符个数。若此值为零,函数返回缓冲区所必需的 宽字符数,在这种情况下,lpWideCharStr中的缓冲区不被使用。
                _In_ int cchWideChar
                );


CodePage(代码页)

:CP_ACP:ANSI字符集;                   CP_MACCP:Macintosh 代码页;                      CP_OEMCP:OEM代码页;

CP_SYMBOL:符号字符集;             CP_THREAD_ACP:当前线程ANSI代码页;

CP_UTF7:使用UTF-7转换;             CP_UTF8:使用UTF-8转换。

// 函数功能:该函数映射一个unicode字符串到一个多字节字符串。
// 函数原型:
        int WideCharToMultiByte(
            // 指定执行转换的 代码页
            _In_ UINT CodePage,

            // 允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符
            _In_ DWORD dwFlags,

            // 指定要转换为宽字节字符串的缓冲区
            _In_NLS_string_(cchWideChar) LPCWCH lpWideCharStr, 

            // 指定由参数lpWideCharStr指向的缓冲区的字符个数
            _In_ int cchWideChar,

            // 指向接收被转换字符串的缓冲区
            _Out_writes_bytes_to_opt_(cbMultiByte,return) LPSTR lpMultiByteStr, 

            // 指定由参数lpMultiByteStr指向的 缓冲区最大值
            _In_ int cbMultiByte,

            // 遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符
            _In_opt_ LPCCH lpDefaultChar,

            // 至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE
            _Out_opt_ LPBOOL lpUsedDefaultChar
            );

使用方法

由于转换前不知道转换后的字符长度,无法定义合适大小的变量存放转换后的字符,所以使用预转换的方法。

1. 将要转换的字符串传递给参数,接收缓冲置为缺省,接收缓冲大小为0,从返回值中获得转换后的字符数。(预转换)

2. 根据返回的字符数分配空间

3. 再次调用转换函数,并将分配的空间传递给转换函数,得到结果。

转换示例

#define ANSI_TO_UTF8(dst, src)  dst = Transform(src, CP_ACP, CP_UTF8);
#define UTF8_TO_ANSI(dst, src)  dst = Transform(src, CP_UTF8, CP_ACP); 

string Transform(string str, int sourceCodepage, int targetCodepage)
{
    int dstLen = MultiByteToWideChar(sourceCodepage, 0, str.c_str(), -1, NULL, 0);

    wchar_t *pUnicode = new wchar_t[dstLen + 1];
    memset(pUnicode, 0, (dstLen + 1) * sizeof(wchar_t));

    MultiByteToWideChar(sourceCodepage, 0, str.c_str(), -1, (LPWSTR)pUnicode, (int)dstLen);

    dstLen = WideCharToMultiByte(targetCodepage, 0, (LPWSTR)pUnicode, -1, NULL, NULL, NULL, NULL);
    
    BYTE *pTargetData = new BYTE[dstLen + 1];
    memset(pTargetData, 0, dstLen + 1);

    WideCharToMultiByte(targetCodepage, 0, (LPWSTR)pUnicode, -1, (char *)pTargetData, dstLen, NULL, NULL);

    string retstr = (char *)pTargetData;

    delete[] pUnicode;
    delete[] pTargetData;

    return retstr;
}



版权声明:本文为qq_43142808原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。