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

字符乱码 字符编码 编码转换,该如何解决

2014-01-12 
字符乱码 字符编码 编码转换我长话短说:用GET从HTTP上请求了数据,用recv函数直接收到了char *buffer中,在V

字符乱码 字符编码 编码转换
我长话短说:
用GET从HTTP上请求了数据,用recv函数直接收到了char *buffer中,在VS中查看结果
HTTP/1.1 200 OK Date: Thu, 09 Jan 2014 01:29:15 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 2.0.50727 Cache-Control: private Expires: Thu, 09 Jan 2014 01:29:15 GMT Content-Type: text/html; charset=utf-8 Content-Length: 387 

[ { "GUID": "", "OID": -1, "ID": 4002, "UserID": null, "Name": "鏉庢瘏", "Sex": null, "NationCode": null, "Birthday": null, "IdentityCardID": null, "AreaCode": null, "HomeAddress": null, "WorkAddress": null, "TelephoneNum": null, "MobilePhoneNum": null, "NameSpell": null, "BabyName": "鏉庢檽鑹? } ]

问题来了,中文乱码了。。。
问题1:HTTP头信息中的charset=utf-8 是说下面的数据是utf-8编码的吗?
问题2:为什么中文会乱码?

我对buffer做了编码转换:
int m = MultiByteToWideChar(CP_UTF8,0,buffer,-1,0,0);
WCHAR *temp = new WCHAR[m+1];
temp[m]='\0';
MultiByteToWideChar(CP_UTF8,0,buffer,-1,temp,m); 

temp中信息如下:
HTTP/1.1 200 OK Date: Thu, 09 Jan 2014 01:29:15 GMT Server: Microsoft-IIS/6.0 X-Powered-By: ASP.NET X-AspNet-Version: 2.0.50727 Cache-Control: private Expires: Thu, 09 Jan 2014 01:29:15 GMT Content-Type: text/html; charset=utf-8 Content-Length: 387 

[ { "GUID": "", "OID": -1, "ID": 4002, "UserID": null, "Name": "李毅", "Sex": null, "NationCode": null, "Birthday": null, "IdentityCardID": null, "AreaCode": null, "HomeAddress": null, "WorkAddress": null, "TelephoneNum": null, "MobilePhoneNum": null, "NameSpell": null, "BabyName": "李晓艺" } ]

中文乱码的问题解决了,但是将字符串存在WCHAR中不方便,我想转成CHAR中存储,所以我又:
m=WideCharToMultiByte(CP_UTF8,0,temp,-1,0,0,0,0);
char *result = new char[m+1];
result[m]='\0';
WideCharToMultiByte(CP_UTF8,0,temp,-1,result,m,0,0);

结果又显示乱码。。。。

问题3:为什么转换成UNICODE编码的WCHAR就不乱码了?
问题4:应该如何正确的从不乱码的WCHAR转到不乱码的CHAR?

谢谢
[解决办法]
问题1:HTTP头信息中的charset=utf-8 是说下面的数据是utf-8编码的吗?

问题2:为什么中文会乱码?
一个孤立的字符串的解释依赖于具体的系统,你如果在linux上开发,utf8的默认显示的是正确的,而如果你转成wchar_t反而会乱码。html/xml通过charset属性指明了对这些字节流的理解方式,所以不同平台上都可以正确显示。在各个系统的底层,可能都要转换成特定的编码方式再显示,比如utf-8的串在Windows上会转成unicode, unicode/gbk等编码方式的在linux下多半会转换成utf8串再显示。

问题3:为什么转换成UNICODE编码的WCHAR就不乱码了?
wchar是你的操作系统默认的理解方式,所以它理解了,你看不到乱。
问题4:应该如何正确的从不乱码的WCHAR转到不乱码的CHAR?
你可以以utf8或GBK编码来保存/运算,显示的时候再转换成wchar_t串。


[解决办法]
中文乱码的问题解决了,但是将字符串存在WCHAR中不方便,我想转成CHAR中存储,所以我又:
m=WideCharToMultiByte(CP_ACP,0,temp,-1,0,0,0,0);
char *result = new char[m+1];
result[m]='\0';
WideCharToMultiByte(CP_ACP,0,temp,-1,result,m,0,0);

同样的二进制数据在不同的字符集中对应不同的字符,要把二进制数据作为文本显示必须指定字符集
高版本的VS在调试中显示数据时,对于wchar_t*指针指向的内存,按照UNICODE编码来对应字符集,对于char*指针指向的内存,按照ASCII编码和操作系统语言设置来对应字符集。当然这些都是显示方面的功能,对于程序本身执行的功能一点影响都没有。
此外,如果想在WINDOW下发展,楼主最好习惯使用WCHAR等等UNICODE编码。因为WINDOWS现在的内核全部是UNICODE的,所有你使用的A版本函数不仅受操作系统语言设置影响,而且执行时都由操作系统额外执行一个MultiByteToWideChar后再处理。
[解决办法]
关于问题2:
是说乱码的原因是操作系统不能理解utf8的编码而HTTP发来的正好又是utf8编码的信息,所以出现乱码?
------------------
如果你告诉它这个是utf8串,那它会理解,但你不告诉它它不会把所有可能的字符编码方式逐一试遍。


高版本的VS在调试中显示数据时,对于wchar_t*指针指向的内存,按照UNICODE编码来对应字符集,对于char*指针指向的内存,按照ASCII编码和操作系统语言设置来对应字符集。
--------------------
根据这个信息,转换成gbk应该就不会显示乱码了。中文转成utf8没有任何存储上的优势。

热点排行