c++ 字符集转换

转码整理, 资料来源于网络

charset.h

#pragma once

#include <iostream>
#include <string>

std::string  UnicodeToAnsi(const std::wstring& unicode);
std::wstring AnsiToUnicode(const std::string& ansi);

std::string  AnsiToUtf8(const std::string& strSrc);
std::string  Utf8ToAnsi(const std::string& strSrc);

std::string  UnicodeToUtf8(const std::wstring& wstrSrc);
std::wstring Utf8ToUnicode(const std::string& strSrc);

std::string  GBKToUtf8(const std::string& gbk);
std::string  Utf8ToGBK(const std::string& utf8);

std::wstring GB2312ToUnicode(const std::string& gb2312);
std::string  UnicodeToGB2312(const std::wstring& unicode);

std::wstring BIG5ToUnicode(const std::string& big5);
std::string  UnicodeToBIG5(const std::wstring& unicode);

std::string  FBIG5ToGB2312(const std::string& big5);
std::string  GB2312ToFBIG5(const std::string gb2312);

bool IsUTF8(const void* pBuffer, long size);

main.cpp

#include "charset.h"

void showHex(const char* bytes, int len) {
    for (int i = 0; i < len; i++) {
        printf("%02x ", (unsigned char)bytes[i]);
    }
}

void showHex(std::string charset, std::string str) {
    printf("%10s: ", charset.data());
    showHex(str.data(), str.size());
    printf("\n");
}

void showHex(std::string charset, std::wstring str) {
    printf("%10s: ", charset.data());
    showHex((char*)str.data(), 2 * str.size());
    printf("\n");
}

int main(int argc, char* argv[])
{
    std::wstring wstr(L"中abc国");
    std::string str("中abc国");

    std::string ansi;
    std::string utf8;
    std::string gbk;
    std::wstring unicode;

    showHex("unicode", wstr);
    showHex("ansi", str);

    ansi = UnicodeToAnsi(wstr); showHex("ansi", ansi);

    unicode = AnsiToUnicode(ansi); showHex("unicode", unicode);

    utf8 = AnsiToUtf8(str); showHex("utf8", utf8);
    ansi = Utf8ToAnsi(utf8); showHex("ansi", ansi);

    utf8 = UnicodeToUtf8(wstr); showHex("utf8", utf8);
    unicode = Utf8ToUnicode(utf8); showHex("unicode", unicode);

    gbk = Utf8ToGBK(utf8); showHex("gbk", gbk);
    utf8 = GBKToUtf8(gbk); showHex("utf8", utf8);

    getchar();
    return 0;
}

charset.cpp

#inchude "charset.h"
#include <Windows.h>

std::string UnicodeToAnsi(const std::wstring& unicode)
{
    LPCWCH ptr = unicode.c_str();
    /** 分配目标空间, 一个16位Unicode字符最多可以转为4个字节int size = static_cast<int>( wstrSrc.size() * 4 + 10 );*/
    int size = WideCharToMultiByte(CP_THREAD_ACP, 0, ptr, -1, NULL, 0, NULL, NULL);

    std::string strRet(size, 0);
    int len = WideCharToMultiByte(CP_THREAD_ACP, 0, ptr, -1, (LPSTR)strRet.c_str(), size, NULL, NULL);

    return strRet;
}

std::wstring AnsiToUnicode(const std::string& ansi)
{
    LPCCH ptr = ansi.c_str();
    int size = MultiByteToWideChar(CP_ACP, 0, ptr, -1, NULL, NULL);

    std::wstring wstrRet(size, 0);
    int len = MultiByteToWideChar(CP_ACP, 0, ptr, -1, (LPWSTR)wstrRet.c_str(), size);

    return wstrRet;
}

std::string AnsiToUtf8(const std::string& ansi)
{
    LPCCH ptr = ansi.c_str();
    /* 分配目标空间, 长度为 Ansi 编码的两倍 */
    int size = MultiByteToWideChar(CP_ACP, 0, ptr, -1, NULL, NULL);

    std::wstring wstrTemp(size, 0);
    int len = MultiByteToWideChar(CP_ACP, 0, ptr, -1, (LPWSTR)wstrTemp.c_str(), size);

    return UnicodeToUtf8(wstrTemp);
}

std::string Utf8ToAnsi(const std::string& utf8)
{
    std::wstring wstrTemp = Utf8ToUnicode(utf8);

    LPCWCH ptr = wstrTemp.c_str();
    int size = WideCharToMultiByte(CP_ACP, 0, ptr, -1, NULL, 0, NULL, NULL);

    std::string strRet(size, 0);
    int len = WideCharToMultiByte(CP_ACP, 0, ptr, -1, (LPSTR)strRet.c_str(), size, NULL, NULL);

    return strRet;
}

std::string UnicodeToUtf8(const std::wstring& unicode)
{
    /* 分配目标空间, 一个16位Unicode字符最多可以转为4个字节 */
    LPCWCH ptr = unicode.c_str();
    int size = WideCharToMultiByte(CP_UTF8, 0, ptr, -1, NULL, 0, NULL, NULL);

    std::string strRet(size, 0);
    int len = WideCharToMultiByte(CP_UTF8, 0, ptr, -1, (char*)strRet.c_str(), size, NULL, NULL);

    return strRet;
}

std::wstring Utf8ToUnicode(const std::string& utf8)
{
    LPCCH ptr = utf8.c_str();
    int size = MultiByteToWideChar(CP_UTF8, 0, ptr, -1, NULL, NULL);

    std::wstring wstrRet(size, 0);
    int len = MultiByteToWideChar(CP_UTF8, 0, ptr, -1, (LPWSTR)wstrRet.c_str(), size);

    return wstrRet;
}

std::string GBKToUtf8(const std::string& gbk)
{
    return AnsiToUtf8(gbk);
}

std::string Utf8ToGBK(const std::string& utf8)
{
    return Utf8ToAnsi(utf8);
}

bool IsUTF8(const void* pBuffer, long size)
{
    bool isUTF8 = true;
    unsigned char* start = (unsigned char*)pBuffer;
    unsigned char* end = (unsigned char*)pBuffer + size;
    while (start < end)
    {
        if (*start < 0x80) { /*(10000000): 值小于0x80的为ASCII字符*/
            start++;
        }
        else if (*start < (0xC0)) { /*(11000000): 值介于0x80与0xC0之间的为无效UTF-8字符*/
            isUTF8 = false;
            break;
        }
        else if (*start < (0xE0)) { /*(11100000): 此范围内为2字节UTF-8字符  */
            if (start >= end - 1) {
                break;
            }
            if ((start[1] & (0xC0)) != 0x80) {
                isUTF8 = false;
                break;
            }
            start += 2;
        }
        else if (*start < (0xF0)) { /**(11110000): 此范围内为3字节UTF-8字符*/
            if (start >= end - 2) {
                break;
            }
            if ((start[1] & (0xC0)) != 0x80 || (start[2] & (0xC0)) != 0x80) {
                isUTF8 = false;
                break;
            }
            start += 3;
        }
        else {
            isUTF8 = false;
            break;
        }
    }

    return isUTF8;
}

//GB2312 转换成 Unicode
std::wstring GB2312ToUnicode(const std::string& gb2312)
{
    UINT nCodePage = 936; //GB2312
    int size = MultiByteToWideChar(nCodePage, 0, gb2312.c_str(), -1, NULL, 0);

    std::wstring wstrRet(size, 0);
    MultiByteToWideChar(nCodePage, 0, gb2312.c_str(), -1, (LPWSTR)wstrRet.c_str(), size);

    return wstrRet;
}

//BIG5 转换成 Unicode
std::wstring BIG5ToUnicode(const std::string& big5)
{
    UINT nCodePage = 950; //BIG5
    int size = MultiByteToWideChar(nCodePage, 0, big5.c_str(), -1, NULL, 0);

    std::wstring wstrRet(size, 0);
    MultiByteToWideChar(nCodePage, 0, big5.c_str(), -1, (LPWSTR)wstrRet.c_str(), size);

    return wstrRet;
}

//Unicode 转换成 GB2312
std::string UnicodeToGB2312(const std::wstring& unicode)
{
    UINT nCodePage = 936; //GB2312
    int size = WideCharToMultiByte(nCodePage, 0, unicode.c_str(), -1, NULL, 0, NULL, NULL);

    std::string strRet(size, 0);
    WideCharToMultiByte(nCodePage, 0, unicode.c_str(), -1, (LPSTR)strRet.c_str(), size, NULL, NULL);

    return strRet;
}

//Unicode 转换成 BIG5
std::string UnicodeToBIG5(const std::wstring& unicode)
{
    UINT nCodePage = 950; //BIG5
    int size = WideCharToMultiByte(nCodePage, 0, unicode.c_str(), -1, NULL, 0, NULL, NULL);

    std::string strRet(size, 0);
    WideCharToMultiByte(nCodePage, 0, unicode.c_str(), -1, (LPSTR)strRet.c_str(), size, NULL, NULL);

    return strRet;
}

//繁体中文BIG5 转换成 简体中文 GB2312
std::string FBIG5ToGB2312(const std::string& big5)
{
    LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_PRC);
    std::wstring unicode = BIG5ToUnicode(big5);

    std::string gb2312 = UnicodeToGB2312(unicode);
    int size = LCMapStringA(lcid, LCMAP_SIMPLIFIED_CHINESE, gb2312.c_str(), -1, NULL, 0);

    std::string strRet(size, 0);
    LCMapStringA(0x0804, LCMAP_SIMPLIFIED_CHINESE, gb2312.c_str(), -1, (LPSTR)strRet.c_str(), size);

    return strRet;
}

//简体中文 GB2312 转换成 繁体中文BIG5
std::string GB2312ToFBIG5(const std::string gb2312)
{
    LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), SORT_CHINESE_PRC);
    int size = LCMapStringA(lcid, LCMAP_TRADITIONAL_CHINESE, gb2312.c_str(), -1, NULL, 0);

    std::string strRet(size, 0);
    LCMapStringA(lcid, LCMAP_TRADITIONAL_CHINESE, gb2312.c_str(), -1, (LPSTR)strRet.c_str(), size);

    std::wstring unicode = GB2312ToUnicode(strRet);
    std::string big5 = UnicodeToBIG5(unicode);

    return big5;
}
时间: 2024-08-30 03:36:16

c++ 字符集转换的相关文章

libiconv字符集转换库在C#中的使用

<libiconv字符集转换库使用方法>一文中说到了libiconv可以实现不同字符集的转换.比如GBK转BIG5等.在项目中因为需要,找到这个库.可是这个库在C#中没有很好的支持.不过,想着既然是C++的库,那只要动态加载DLL的接口就好了.可是调用并不顺利,传进去的IntPtr或者byte数组总是拿不到数据.后面回到了C++的方式去调用,几经调试,总算找到了原因. 是iconv接口在转换完成后,指针的位置往后移了.而在C#中调用DLL后回来的指针,已经是移动后的,所以拿不到所要的数据. 经

iconv_open函数申请一个字符集转换的描述符

iconv_open函数 iconv_open函数 iconv_open——申请一个字符集转换的描述符 #include <iconv.h> iconv_t iconv_open(const char* tocode,const char* fromcode) 描述: iconv_open()函数申请一个转换描述符,转换字符序列从编码fromcode到编码tocode 转换描述符包含转换状态,调用iconv_open创建以后,转换状态处于初始状态,调用iconv函数以后改变转换描述符的转换状态

Python任意字符集转换

在python处理文本的过程中,经常会有文本字符集转换的情况, 而我们希望用一个方法,不用关心文本原本的字符集是什么样的,直接转换成想要的任何字符集就可以了. 方法一: import chardet def convert_encoding(data,new_coding='UTF-8'): # 任意字符集转换 encoding = chardet.detect(data)['encoding'] if new_coding.upper() != encoding.upper(): data =

字符集转换引发插入乱码问题

根据http://www.cnblogs.com/cchust/p/4601536.html进行验证测试 问题背景 在mysql上面执行一条普通的insert语句,结果报错: Incorrect string value: '\x91;offl...' for column 'c' at row 1 重现: 1)连接MySQL字符集是UTF8 mysql --default-character-set=utf8 test 2)表结构 CREATE TABLE `abc` ( `id` int(1

Oracle字符集转换

这几天在工作中碰到一个字符乱码的问题,发现在cmd窗口的sqlplus中直接update一个中文和使用@调用一个文件作同样更新的时候,存储的结果 竟不一样.一时比较迷惑,对Oracle如何处理各个字符集的问题不是很清楚.特此通过一些资料和实验总结,系统学习一下Oracle中字符集的相关知 识. 一. 字符集的基础知识:在网络上已有不少网友对字符集进行了研究,个人觉得有几个不错的网站可以参考http://blog.csdn.net/tianlesoftware/article/details/49

Lazarus 字符集转换 Utf8ToAnsi,UTF8ToWinCP,UTF8ToSys,UTF8ToConsole

由于Lazarus从1.2版开始默认字符集就是UTF8,如果要转到系统正常显示或文本保存,就必须对字符集进行转换.Lazarus提供了很多函数.如题. 那么这里面有什么关系呢? UTF8ToSys 需要 启用编译参数 –dDisableUTF8RTL,否则还是UTF8,如果变码还是Utf8ToAnsi,但做了基本的处理. 对应代码 function UTF8ToSys(const s: string): string; begin {$IFDEF UTF8_RTL} Result:=s; {$E

【Teradata】Latin和Unicode字符集转换(自定义函数udf_w936to16和udf16tow936)

1.安装UDF函数 (1)下载GBK2Unicode.zip,地址为https://downloads.teradata.com/tag/udf (2)windows或者Linux环境下使用bteq进行安装. 进入文件所在目录,输入如下命令(windows中使用dos) bteq .logon 192.168.253.222/citic_edw 输入口令后,输入如下命令 database syslib; .run file=16_936.sql 验证syslib库中是否存在udf_w936to1

oracle 字符集转换:AL32UTF8-&gt;ZHS16GBK

select userenv('language') from dual; --修改Oracle数据库字符集为ZHS16GBK : SQL>conn / as sysdba; SQL>shutdown immediate; SQL>startup mount; SQL>alter system enable restricted session; SQL>alter system set job_queue_processes=0; SQL>alter system s

linux文件字符集转换

[email protected]:~$ locale -a 查看本地字符集[email protected]:~$ locale -m 查看所有支持的字符集 file -i input.txt   查看文件字符集 将文件从gb2312转为utf8iconv -f gb2312 -t utf8  input.txt -o output.txt