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

alang512 2013-12-08 02:48:24
请问,各位熟悉编码方式的,为什么在转换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;
}
...全文
1557 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
5t4rk 2013-12-10
  • 打赏
  • 举报
回复
解决就好。不客气
lm_whales 2013-12-10
  • 打赏
  • 举报
回复
引用 17 楼 bjtbjt 的回复:
收藏
Todd_Pointer 2013-12-09
  • 打赏
  • 举报
回复
应该使用 swprintf,或者_sprintf_l。(这二者应该都是MS扩展)。 另外如果你的代码文件以utf-8格式保存,"中国" 应该就是utf-8编码的。 或者使用c++11的 u8"中国"
引用 13 楼 u012908616 的回复:
sprintf之后再转成UTF8。 sprintf很可能无法正确处理utf-8字符
Todd_Pointer 2013-12-09
  • 打赏
  • 举报
回复
sprintf之后再转成UTF8。 sprintf很可能无法正确处理utf-8字符
alang512 2013-12-09
  • 打赏
  • 举报
回复
谢谢 17 楼的代码,终于解决了翻译程序的编码问题了,实现了英汉互译功能了。 基本思路是
	CString  strText;
	GetDlgItemText(IDC_EDIT1,strText);
	if(strText.GetLength()<=0)
	{
		MessageBox("请输入你要翻译的内容");
		return ;
	}
	char pTransText[200];
	memset(pTransText,0,200);
    
	string  strUTF8;
    strUTF8=UrlUTF8(strText.GetBuffer(strText.GetLength()));

	strcpy(pTransText,strUTF8.c_str());// 
 	char pURL[700];
 	memset(pURL,0,700);
 	sprintf(pURL,"%s%s",strURL,pTransText);
 
	pHttpFile=pHttpConnection->OpenRequest("GET",pURL);
Exaybachay 2013-12-09
  • 打赏
  • 举报
回复
有道不认识, 可能缺少 BOM 头, 你加上试试. 什么是 BOM 头, 你搜搜. 再不行, 先把文本写到文件中, 用记事本打开看看.
赵4老师 2013-12-09
  • 打赏
  • 举报
回复
对电脑而言没有乱码,只有二进制字节;对人脑才有乱码。啊 GBK:0xB0 0xA1,Unicode-16 LE:0x4A 0x55,Unicode-16 BE:0x55 0x4A,UTF-8:0xE5 0x95 0x8A
alang512 2013-12-09
  • 打赏
  • 举报
回复
17楼的代码,似曾相识,跟之前在网上找的有点类似,希望今晚下班回去之后,能按照提供你代码解决这个问题,谢谢 楼上的各位了,若等我实现了,我也会在此分享 下自己的代码: 有道中英互译程序
赵4老师 2013-12-09
  • 打赏
  • 举报
回复
仅供参考,尽管是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

5t4rk 2013-12-09
  • 打赏
  • 举报
回复
//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()));
alang512 2013-12-09
  • 打赏
  • 举报
回复
谢谢各位的热心解答,可是我还是无法解决问题, 我是VC6.0编写一个基于有道翻译API的翻译程序,其中就是使用htt协议来实现,在提交中文字符内容时,必须是UTF8编码格式,否则有道那边无法返回正确的翻译内容,即无法实现中文翻译为英文。 哪位,是否以前也碰到过 中文字符转换为UTF8的,麻烦说下,谢谢了。
lm_whales 2013-12-09
  • 打赏
  • 举报
回复
引用 9 楼 alang512 的回复:
[quote=引用 8 楼 lm_whales 的回复:] WideCharToMultiByte是转MBCS的,不是转UTF8的。 UTF8,只是一种方便的编码,不是一种国家或者国际标准。
那请问,到底该如何才能提交UTF8的 中文字符 啊,因为有道翻译那边要求提交数据是 UTF8的[/quote] 搜一下UTF8 的代码转换器或者库,不然使用支持UTF8的操作系统,和编译器 好象C++ 11 支持 UTF8字符串。 个人感觉 UTF8 这个好东西,会造成更大的混乱。 因为现在有三种字符类型数据,都是 char 类型。 1)ASCII //美国政府---美国相关标准机构--制定的标准。 //1字节表示。 2)MBCS //各国或者地区---制定的标准,在计算机内的实现。 //1~2 字节表示(汉字),1~n字节表示(其他语言)。 3)UTF8 //(linux 社区?互联网??)产生的标准或者实践。 //1~3?个字节表示。 UTF8 和 MBCS一样是一种变长编码。 可能需要自己做个转换器。
alang512 2013-12-08
  • 打赏
  • 举报
回复
引用 8 楼 lm_whales 的回复:
WideCharToMultiByte是转MBCS的,不是转UTF8的。 UTF8,只是一种方便的编码,不是一种国家或者国际标准。
那请问,到底该如何才能提交UTF8的 中文字符 啊,因为有道翻译那边要求提交数据是 UTF8的
lm_whales 2013-12-08
  • 打赏
  • 举报
回复
WideCharToMultiByte是转MBCS的,不是转UTF8的。 UTF8,只是一种方便的编码,不是一种国家或者国际标准。
alang512 2013-12-08
  • 打赏
  • 举报
回复
引用 5 楼 Exaybachay 的回复:
utf8 直管发送就是, 对方自然能够理解. 如果要显示, 要么用本地locale(GBK,GB2312) 要么用unicode utf8 只是 unicode 的一种传输编码, 本质还是 unicode 的
那为什么我提交的数据,结果在 读取有道翻译那边返回的数据是乱码,而且提示: 无法进行有效的翻译, 如果提交英文字符,则能够翻译为中文。
Exaybachay 2013-12-08
  • 打赏
  • 举报
回复
所以, 严格意义上, utf8 算不上一种编码
Exaybachay 2013-12-08
  • 打赏
  • 举报
回复
utf8 直管发送就是, 对方自然能够理解.
如果要显示, 要么用本地locale(GBK,GB2312)
要么用unicode

utf8 只是 unicode 的一种传输编码,
本质还是 unicode 的
alang512 2013-12-08
  • 打赏
  • 举报
回复
引用 3 楼 truexf 的回复:
UTF8字符串在调试的时候显示乱码很正常,因为你的调试环境把char*当成多字节字符串对待
请问, 该如何将 Unicode中文字符转换为UTF8,因为我要上传UTF8中文字符 wchar_t pUnicode[]=L"中国"; char* pTransText; pTransText=UnicodeToUTF_8(pUnicode); char pURL[700]; memset(pURL,0,700); sprintf(pURL,"%s%s",strURL,pTransText); pHttpFile=pHttpConnection->OpenRequest("GET",pURL);
「已注销」 2013-12-08
  • 打赏
  • 举报
回复
UTF8字符串在调试的时候显示乱码很正常,因为你的调试环境把char*当成多字节字符串对待
加载更多回复(2)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧