[编程笔记] UNICODE和UTF-8和ASCII互转

转载地址:https://blog.csdn.net/fzuim/article/details/72729833

此代码是在windows平台上运行。

最近维护一个项目时发现,MFC的Cstring类型写到ini文本时,出现了乱码。因为写入的数据带有类似的特殊字符❀,由于ini默认创建的编码格式为GBK编码格式,但是这个特殊字符在默认的GBK编码下是不能识别的,会以?的形式存在。那这个特殊字符的编码是什么,暂时还没搞清楚。但是既然知道存在这样的bug,那么我们就有了相应的解决方法:在写入ini文件时,先将unicode编码的内容转成utf-8(utf-8具有世界通用性,所以显示这个特殊字符不在话下)再写入到ini文件,显然在GBK编码的ini文件中显示UTF-8编码的内容肯定是乱码,比如中文或者特殊字符。当我们要取出写入ini文件的内容时,我们又需要进行一次转码,将UTF-8转成UNICODE编码。

源码如下:

//UTF8转Unicode
std::wstring UTF8ToUnicode(const char *v_szUTF8)
{
    std::wstring wstrUnicode;
    if (NULL == v_szUTF8) {
        return wstrUnicode;
    }
    DWORD dwNum = MultiByteToWideChar(CP_UTF8, 0, v_szUTF8, -1, NULL, 0);
    if (ERROR_NO_UNICODE_TRANSLATION == dwNum) {
        return wstrUnicode;
    }
    if (0 == dwNum) {
        return wstrUnicode;
    }
    WCHAR *wcsUnicode = new WCHAR[dwNum + 1];
    memset(wcsUnicode, 0, (dwNum + 1) * sizeof(WCHAR));

    MultiByteToWideChar(CP_UTF8, 0, v_szUTF8, -1, wcsUnicode, dwNum);
    wstrUnicode = wcsUnicode;
    if (NULL != wcsUnicode) {
        delete [] wcsUnicode;
    }

    return wstrUnicode;
}
//Unicode转UTF8
std::string UnicodeToUTF8(const WCHAR *v_wcsUnicode)
{
    std::string strUTF8;
    if (NULL == v_wcsUnicode) {
        return strUTF8;
    }

    DWORD dwNum = WideCharToMultiByte(CP_UTF8, 0, v_wcsUnicode, -1, NULL, 0, NULL, 0);
    if (0 == dwNum) {
        return strUTF8;
    }
    char *szUTF8 = new char[dwNum + 1];
    memset(szUTF8, 0, (dwNum + 1) * sizeof(char));
    
    //将宽字节字符串转换为多字节字符串
    WideCharToMultiByte(CP_UTF8, 0, v_wcsUnicode, -1, szUTF8, dwNum, NULL, 0);
    strUTF8 = szUTF8;
    if (NULL != szUTF8) {
        delete [] szUTF8;
    }
    return strUTF8;
}
//Unicode转ASCII
std::string UnicodeToASCII(const WCHAR *v_wcsUnicode)
{
    std::string strASCII;
    if (NULL == v_wcsUnicode) {
        return strASCII;
    }

    DWORD dwNum = WideCharToMultiByte(CP_OEMCP, 0, v_wcsUnicode, -1, NULL, 0, NULL, 0);
    if (0 == dwNum) {
        return strASCII;
    }
    char *szASCII= new char[dwNum + 1];
    memset(szASCII, 0, (dwNum + 1) * sizeof(char));

    //将宽字节字符串转换为多字节字符串
    WideCharToMultiByte(CP_OEMCP, 0, v_wcsUnicode, -1, szASCII, dwNum, NULL, 0);
    strASCII = szASCII;
    if (NULL != szASCII) {
        delete [] strASCII;
    }
    return strASCII;
}
//ASCII转Unicode
std::wstring ASCIIToUnicode(const char *v_szASCII)
{
    std::wstring wstrUnicode;
    if (NULL == v_szASCII) {
        return wstrUnicode;
    }
    DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, v_szASCII, -1, NULL, 0);
    if (ERROR_NO_UNICODE_TRANSLATION == dwNum) {
        return wstrUnicode;
    }
    if (0 == dwNum) {
        return wstrUnicode;
    }
    WCHAR *wcsUnicode = new WCHAR[dwNum + 1];
    memset(wcsUnicode, 0, (dwNum + 1) * sizeof(WCHAR));

    MultiByteToWideChar(CP_ACP, 0, v_szASCII, -1, wcsUnicode, dwNum);
    wstrUnicode = wcsUnicode;
    if (NULL != wcsUnicode) {
        delete [] wcsUnicode;
    }
    return wstrUnicode;
}
//UTF8转ASCII
std::string UTF8ToASCII(const char *v_szUTF8)
{
    std::string strASCII;
    if (NULL == v_szUTF8) {
        return strASCII;
    }
    //先把utf8转为unicode
    std::wstring wstrUnicode = UTF8ToUnicode(v_szUTF8);
    //最后把unicode转为ascii
    strASCII = UnicodeToASCII(wstrUnicode.c_str());
    return strASCII;
}
//ASCII转UTF8
std::string ASCIIToUTF8(const char *v_szASCII) 
{
    std::string strUTF8;
    if (NULL == v_szASCII) {
        return strUTF8;
    }
    //先把ascii转为unicode
    std::wstring wstrUnicde = ASCIIToUnicode(v_szASCII);
    //最后把unicode转为utf8
    strUTF8 = UnicodeToUTF8(wstrUnicode.c_str());
    return strUTF8;
}

猜你喜欢

转载自blog.csdn.net/zhangge3663/article/details/83993318
今日推荐