Qt5中的字符串乱码问题

本文探讨了Qt5中字符串乱码问题,尤其是UTF8编码和GBK编码在VS2010和QtCreator中的处理。通过示例代码展示了无BOM UTF8、带BOM UTF8及GBK编码的处理方式,并分析了VC2010对UTF8的支持情况。解决中文乱码的根本方案是确保源文件和编译器编码一致,或者在QString转换时使用正确编码。
摘要由CSDN通过智能技术生成

先例举几种Qt5中QString使用汉字的可能方法与结果:

(以下结果适用用MSVC编译,工程使用Unicode字符集或多字节字符集的情况)  //可以看出,与工程使用何种字符集无关

测试代码

源文件ASCII编码保存

源文件UTF-8无BOM保存

源文件UTF-8且有BOM保存

(需要使用VS2010SP1且加入

#pragram execution_character_set("utf-8"))

QString test = "测试字符串";              结果为乱码; 出现编译错误 结果正确显示字符串“测试字符串”
QString test =
QString::fromLatin1("测试字符串");           
结果为乱码,与1不同; 出现编译错误 结果为乱码
QString test =
QString::fromUtf8("测试字符串");              
结果为乱码,且与1相同; 出现编译错误 结果正确显示字符串“测试字符串”
QString test =
QString::fromUtf16("测试字符串");  
 结果不能通过编译;  出现编译错误 出现编译错误
QString test =
QString::fromWCharArray("测试字符串");
 结果不能通过编译; 出现编译错误 出现编译错误


可以看到使用第三种方法解决了中文乱码问题,这里要注意在每一个被保存为带BOM的Utf-8编码的.cpp文件中需要加上如下预编译语句:

 #if defined(_MSC_VER) && (_MSC_VER >= 1600)     //_MSC_VER是微软C/C++编译器——cl.exe编译代码时预定义的一个宏。
//需要针对cl编写代码时, 可以使用该宏进行条件编译。
# pragma execution_character_set("utf-8")  
#endif  

分析:

(1)保存源文件为Utf-8带Bom编码格式是为了在VS2010与QtCreator中都可以使用同一编码规则打开与修改,如果两方同时使用gb2312编码打开与修改源代码也是可以的,源码中的中文不会出错。

(2)# pragma execution_character_set("utf-8")  预编译命令是告诉编译器在使用字符串时使用utf-8的编码格式,与源文件的编码格式可以说是没有关系的,源文件保存为gb2312编码时仍然可以使用该预编译命令。

(3)由于# pragma execution_character_set("utf-8")  预编译命令在VS2013中已经不再支持.


对于中文乱码问题最根本的解决方案其实是:

(1)在源文件中代码字符串只使用英文,在翻译文件中翻译为中文。

(2)在确实需要将C语言char*类型中文字符串转换为QString类型中文字符串时使用如下方法:

QTextCodec* codec=QTextCodec::codecForName("gb2312");
m_nodeValue = codec->toUnicode(m_clientNode.itemValue);


VS因为为了Windows经常要和ANSI编码(可能是ASCII,也可能混合GBK等多字节编码)区分,所以要求UTF-8之前必须有BOM。Linux因为全盘UTF-8化,UTF-8又和ASCII兼容,而GCC设计者多数也只用英文在程序里,结果好几年Linux只用没有BOM的UTF-8。起始这里处处体现着Linux开发缺乏统一长远计划。Windows因为较早接触国际市场,很早就遇到各种本地编码的问题,所以这方面比较明智(要求UTF-8加BOM)。Linux则对付本地编码的情况不多,所以会有兼容性问题。

 

1。即使把vs设置为识别 NO BOM,文本显示没有问题,但编译还是有问题。通过预编译可以看到。
问题在于有时候,比如:
class A
{
 int a; //测试(utf-8编码会显示乱码,如果解释不好的情况会把下一行作为注释处理)
 int b; (这一行可能会被解释为注释)
}
那么,预编译出来的效果是:
class A
{
  int a;
}

2.解决办法:注释都这样写 /*(空格) 测试(空格)*/
这样,虽然显示是中文乱码,但不会出现上述编译问题。

 

要搞清楚这个问题,先要弄明白编码。但是编码问题实在太复杂,这里肯定讲不开。

我先找一个例子,比如:“中文” 的 Unicode 码点/UTF8编码/GBK 分别是多少。

先去这个网站,输入 “中文” 查询对应的 Unicode 码点/UTF8编码:
http://www.mytju.com/classcode/tools/encode_utf8.asp

Unicode的码点分别是(十进制):中(20013),文(25991)。
对应的UTF8编码分别(16进制): 中(E4B8AD),文(E69687)。

然后再去下面这个网站,输入 “中文” 查询对应的 GBK 编码:
http://www.mytju.com/classcode/tools/encode_gb2312.asp

GBK编码16进制(GBK内码)分别是:中(D6D0),文(CEC4)。

现在已经知道了"中文"的UTF8和GBK编码的具体值。
我们再看看VC2010是怎么处理的。

1. 先看 无 BOM 的 UTF8 编码的代码 (utf8_no_bom.cpp)

01 // utf8 no bom
02 // 文件中包含不能在当前代码页(936)中表示的字符
03 #include <stdio.h>
04   
05 intmain() {
06     constchar* str ="中文";
07     for(inti =0; i < sizeof(str); ++i) {
08         printf("0x%x ", str[i]&0xFF);
09
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值