首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

为何Unicode中文字符转换UTF-8 结果是乱码

2013-12-10 
为什么Unicode中文字符转换UTF-8 结果是乱码请问,各位熟悉编码方式的,为什么在转换UTF8编码之后,结果出现

为什么Unicode中文字符转换UTF-8 结果是乱码
请问,各位熟悉编码方式的,为什么在转换UTF8编码之后,结果出现乱码,不知道哪里出错了

 


wchar_t  pUnicode[]=L"中国";
 
char* pTransText;
pTransText=UnicodeToUTF_8(pUnicode);
CString  strTest=pTransText;
MessageBox(strTest);

char* UnicodeToUTF_8(wchar_t* pText)
{
 
    int u8Len = WideCharToMultiByte(CP_UTF8,NULL,pText,-1,NULL,0,NULL,NULL); 
char* pOut = new char[u8Len + 1]; 
    memset(pOut,0,u8Len + 1);
    WideCharToMultiByte(CP_UTF8,NULL,pText,-1,pOut,u8Len,NULL,NULL); 

    return pOut;
}

[解决办法]
没有错, 也没有乱.
有问题的是:
CString  strTest=pTransText;
char 给 CString , 然后MessageBox显示出来.


[解决办法]
UTF8字符串在调试的时候显示乱码很正常,因为你的调试环境把char*当成多字节字符串对待
[解决办法]
utf8 直管发送就是, 对方自然能够理解.
如果要显示, 要么用本地locale(GBK,GB2312)
要么用unicode

utf8 只是 unicode 的一种传输编码,
本质还是 unicode 的
[解决办法]
所以, 严格意义上, utf8 算不上一种编码
[解决办法]
WideCharToMultiByte是转MBCS的,不是转UTF8的。

UTF8,只是一种方便的编码,不是一种国家或者国际标准。


[解决办法]
http://www.cnblogs.com/xdotnet/archive/2007/11/23/unicode_and_utf8.html
[解决办法]
对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A

[解决办法]
有道不认识, 可能缺少 BOM 头,
你加上试试. 什么是 BOM 头, 你搜搜.

再不行, 先把文本写到文件中, 用记事本打开看看.

[解决办法]
sprintf之后再转成UTF8。 sprintf很可能无法正确处理utf-8字符
[解决办法]
应该使用 swprintf,或者_sprintf_l。(这二者应该都是MS扩展)。

另外如果你的代码文件以utf-8格式保存,"中国" 应该就是utf-8编码的。
或者使用c++11的 u8"中国"

引用:
sprintf之后再转成UTF8。 sprintf很可能无法正确处理utf-8字符

[解决办法]
引用:
Quote: 引用:

WideCharToMultiByte是转MBCS的,不是转UTF8的。

UTF8,只是一种方便的编码,不是一种国家或者国际标准。


那请问,到底该如何才能提交UTF8的 中文字符 啊,因为有道翻译那边要求提交数据是 UTF8的

搜一下UTF8 的代码转换器或者库,不然使用支持UTF8的操作系统,和编译器
好象C++ 11 支持 UTF8字符串。

个人感觉 UTF8 这个好东西,会造成更大的混乱。
因为现在有三种字符类型数据,都是 char 类型。
1)ASCII //美国政府---美国相关标准机构--制定的标准。 
        //1字节表示。
2)MBCS  //各国或者地区---制定的标准,在计算机内的实现。 
        //1~2 字节表示(汉字),1~n字节表示(其他语言)。
3)UTF8  //(linux 社区?互联网??)产生的标准或者实践。
        //1~3?个字节表示。

UTF8 和 MBCS一样是一种变长编码。
可能需要自己做个转换器。

[解决办法]
//header
class strCoding
{
public:
    strCoding(void);
    virtual ~strCoding(void);

    void UTF_8ToGB2312(string &pOut, char *pText, int pLen);//utf_8转为gb2312
    void GB2312ToUTF_8(string& pOut,char *pText, int pLen); //gb2312 转utf_8
    string UrlGB2312(char * str);                           //urlgb2312编码
    string UrlUTF8(char * str);                             //urlutf8 编码
    string UrlUTF8Decode(string str);                       //urlutf8解码
    string UrlGB2312Decode(string str);                     //urlgb2312解码


private:
    void Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer);
    void UTF_8ToUnicode(WCHAR* pOut,char *pText);
    void UnicodeToUTF_8(char* pOut,WCHAR* pText);
    void UnicodeToGB2312(char* pOut,WCHAR uData);
    char CharToInt(char ch);
    char StrToBin(char *str);

};





//cpp
#include "strCoding.h"

strCoding::strCoding(void)
{
}

strCoding::~strCoding(void)
{
}
void strCoding::Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer)
{
    ::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1);
    return;
}

void strCoding::UTF_8ToUnicode(WCHAR* pOut,char *pText)
{
    char* uchar = (char *)pOut;
    
    uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);
    uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);

    return;
}

void strCoding::UnicodeToUTF_8(char* pOut,WCHAR* pText)
{
    // 注意 WCHAR高低字的顺序,低字节在前,高字节在后
    char* pchar = (char *)pText;

    pOut[0] = (0xE0 
[解决办法]
 ((pchar[1] & 0xF0) >> 4));
    pOut[1] = (0x80 
[解决办法]
 ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6);
    pOut[2] = (0x80 
[解决办法]
 (pchar[0] & 0x3F));

    return;
}

void strCoding::UnicodeToGB2312(char* pOut,WCHAR uData)
{
    WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(WCHAR),NULL,NULL);
    return;
}

//做为解Url使用
char strCoding:: CharToInt(char ch){
        if(ch>='0' && ch<='9')return (char)(ch-'0');
        if(ch>='a' && ch<='f')return (char)(ch-'a'+10);
        if(ch>='A' && ch<='F')return (char)(ch-'A'+10);
        return -1;
}
char strCoding::StrToBin(char *str){
        char tempWord[2];
        char chn;

        tempWord[0] = CharToInt(str[0]);                         //make the B to 11 -- 00001011
        tempWord[1] = CharToInt(str[1]);                         //make the 0 to 0 -- 00000000

        chn = (tempWord[0] << 4) 
[解决办法]
 tempWord[1];                //to change the BO to 10110000

        return chn;
}

//UTF_8 转gb2312
void strCoding::UTF_8ToGB2312(string &pOut, char *pText, int pLen)
{
     char buf[4];
     char* rst = new char[pLen + (pLen >> 2) + 2];
    memset(buf,0,4);
    memset(rst,0,pLen + (pLen >> 2) + 2);

    int i =0;
    int j = 0;
     
    while(i < pLen)
    {
        if(*(pText + i) >= 0)
        {
           
            rst[j++] = pText[i++];
        }
        else                
        {
            WCHAR Wtemp;

           
            UTF_8ToUnicode(&Wtemp,pText + i);


             
            UnicodeToGB2312(buf,Wtemp);
           
            unsigned short int tmp = 0;
            tmp = rst[j] = buf[0];
            tmp = rst[j+1] = buf[1];
            tmp = rst[j+2] = buf[2];

            //newBuf[j] = Ctemp[0];
            //newBuf[j + 1] = Ctemp[1];

            i += 3;   
            j += 2;  
        }
       
}
    rst[j]='\0';
   pOut = rst;
    delete []rst;
}

//GB2312 转为 UTF-8
void strCoding::GB2312ToUTF_8(string& pOut,char *pText, int pLen)
{
    char buf[4];
    memset(buf,0,4);

    //pOut.clear();

    int i = 0;
    while(i < pLen)
    {
        //如果是英文直接复制就可以
        if( pText[i] >= 0)
        {
            char asciistr[2]={0};
            asciistr[0] = (pText[i++]);
            pOut.append(asciistr);
        }
        else
        {
            WCHAR pbuffer;
            Gb2312ToUnicode(&pbuffer,pText+i);

            UnicodeToUTF_8(buf,&pbuffer);

            pOut.append(buf);

            i += 2;
        }
    }

    return;
}
//把str编码为网页中的 GB2312 url encode ,英文不变,汉字双字节 如%3D%AE%88
string strCoding::UrlGB2312(char * str)
{
    string dd;
    size_t len = strlen(str);
    for (size_t i=0;i<len;i++)
    {
        if(isalnum((BYTE)str[i]))
        {
            char tempbuff[2];
            sprintf(tempbuff,"%c",str[i]);
            dd.append(tempbuff);
        }
        else if (isspace((BYTE)str[i]))
        {
            dd.append("+");
        }
        else
        {
            char tempbuff[4];
            sprintf(tempbuff,"%%%X%X",((BYTE*)str)[i] >>4,((BYTE*)str)[i] %16);
            dd.append(tempbuff);
        }

    }
    return dd;
}

//把str编码为网页中的 UTF-8 url encode ,英文不变,汉字三字节 如%3D%AE%88
string strCoding::UrlUTF8(char * str)
{
    string tt;
    string dd;
    GB2312ToUTF_8(tt,str,(int)strlen(str));

    size_t len=tt.length();
    for (size_t i=0;i<len;i++)
    {
        if(isalnum((BYTE)tt.at(i)))
        {
            char tempbuff[2]={0};
            sprintf(tempbuff,"%c",(BYTE)tt.at(i));
            dd.append(tempbuff);
        }
        else if (isspace((BYTE)tt.at(i)))


        {
            dd.append("+");
        }
        else
        {
            char tempbuff[4];
            sprintf(tempbuff,"%%%X%X",((BYTE)tt.at(i)) >>4,((BYTE)tt.at(i)) %16);
            dd.append(tempbuff);
        }

    }
    return dd;
}
//把url GB2312解码
string strCoding::UrlGB2312Decode(string str)
{
   string output="";
        char tmp[2];
        int i=0,idx=0/*,ndx*/,len=str.length();
       
        while(i<len){
                if(str[i]=='%'){
                        tmp[0]=str[i+1];
                        tmp[1]=str[i+2];
                        output += StrToBin(tmp);
                        i=i+3;
                }
                else if(str[i]=='+'){
                        output+=' ';
                        i++;
                }
                else{
                        output+=str[i];
                        i++;
                }
        }
       
        return output;
}
//把url utf8解码
string strCoding::UrlUTF8Decode(string str)
{
     string output="";

    string temp =UrlGB2312Decode(str);//

    UTF_8ToGB2312(output,(char *)temp.data(),strlen(temp.data()));

    return output;

}



调用示例

strCoding myStrCoding;

string strNameEncode = myStrCoding.UrlUTF8(m_strUserName.GetBuffer(m_strUserName.GetLength()));


[解决办法]
仅供参考,尽管是VB6:
Private Declare Function MultiByteToWideChar Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByRef lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByRef lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long
'常用的代码页:
const cpUTF8   =65001
const cpGB2312 =  936
const cpGB18030=54936
const cpUTF7   =65000
Function MultiByteToUTF16(UTF8() As Byte, CodePage As Long) As String
    Dim bufSize As Long
    bufSize = MultiByteToWideChar(CodePage, 0&, UTF8(0), UBound(UTF8) + 1, 0, 0)
    MultiByteToUTF16 = Space(bufSize)
    MultiByteToWideChar CodePage, 0&, UTF8(0), UBound(UTF8) + 1, StrPtr(MultiByteToUTF16), bufSize
End Function

Function UTF16ToMultiByte(UTF16 As String, CodePage As Long) As Byte()
    Dim bufSize As Long
    Dim arr() As Byte
    bufSize = WideCharToMultiByte(CodePage, 0&, StrPtr(UTF16), Len(UTF16), 0, 0, 0, 0)


    ReDim arr(bufSize - 1)
    WideCharToMultiByte CodePage, 0&, StrPtr(UTF16), Len(UTF16), arr(0), bufSize, 0, 0
    UTF16ToMultiByte = arr
End Function

Private Sub Command1_Click()
    MsgBox MultiByteToUTF16(UTF16ToMultiByte("ab中,c", cpUTF8), cpUTF8)
End Sub

热点排行