【php精品源码栏目提醒】:本文主要为网学会员提供“QT中文_乱码解决 - 其它资料”,希望对需要QT中文_乱码解决 - 其它资料网友有所帮助,学习一下!
QString 与中文问题2010-07-11 17:04更新:本文的姊妹篇 Qt 中 translate、tr 关系 与中文问题 首先呢,声明一下,QString 是不存在中文支持问题的,很多人遇到问题,并不是本身 QString 的问题,而是没有将自己希望的字符串正确赋给 QString。
很简单的问题,我是中文这样写的时候,它是传统的 char 类型的窄字符串,我们需要的只不过是通过某种方式告诉 QString 这四个汉字采用的那种编码。
而问题一般都出在很多用户对自己当前的编码没太多概念,于是一个简 单的 Qt 程序下面这个小程序,估计大家会感到比较亲切。
似乎有相当多的中文用户尝试写过这样的代码:includeincludeint mainint argc char argv QApplication appargc argv QString a 我是汉字 QLabel labela label.show return app.exec编码,保存,编译,运行,一切都很顺利,可是结果呢: 多数用户看到 其他用户看到 × ‘±‰ —出乎意料,界面上中文没显示出来,出现了不认识字符。
于是开始用搜索引擎搜索,开始上论坛发帖或抱怨最后被告知,下面的语句之一可以解决问题:QTextCodec::setCodecForCStringsQTextCodec::codecForNameGB2312QTextCodec::setCodecForCStringsQTextCodec::codecForNameUTF-8两条指令挨个一试,确实可以解决多数用户是第一条,其他用户是第二条。
那么,为什么会这样呢?两种乱码什么时候出现对这个问题,我想大家可能都有话说。
在继续之前,我们先列个表,看看两种乱码分别在那种情况下出现:我们只列举大家最常用的 3 个编译器微软 VS 的中的 cl,Mingw 中的 g,Linux下的 g,源代码分别采用 GBK 和 不带 BOM 的 UTF-8 以及 带 BOM 的 UTF-8 这3 中编码进行保存。
源代码的编码 编译器 结果 cl 1 GBK mingw-g 1 g 1 cl 2 UTF-8不带 BOM mingw-g 2 g 2 cl 1 UTF-8带 BOM mingw-g 2 g 编译失败采用 3 种不同编码保存的源代码文件,分别用 3 种不同的编译器编译,形成 9种组合,除掉一种不能工作的情况,两种乱码出现的情况各占一半。
从中我们也可以看出,乱码和操作系统原本是没有关系的。
但我们在 Windows 一般用的 GBK,linux 一般用的是不带 BOM 的 UTF-8。
如果我们只考虑带的情况,也可以说两种乱码和系统有关。
QString 为什么会乱码呢真的是 QString 乱码了吗?我们可以问问自己,我们抱怨的对象是不是搞错了?继续之前,先明确几个概念:明确概念 0: 我是汉字 是 C 语言中的字符串,它是 char 型的窄字符串。
上面的例子 可写为const char str 我是汉字QString a str或char str 我是汉字QString a str等明确概念 1: 源文件是有编码的,但是这种纯文本文件却不会记录自己采用的编码这个是问题的根源,不妨做个试验,将前面的源代码保存成 GBK 编码,用 16 进制编辑器能看到引号内是 ce d2 ca c7 ba ba d7 d6 这样 8 个字节。
现在将该文件拷贝到正体繁体中文的 Windows 中,用记事本打开会什么样子呢?... QString a 扂岆荦趼 QLabel labela label.show...那么放到欧美人的 Windows 系统中,再用记事本打开呢?... QString a × QLabel labela label.show...同一个文件,未做任何修改,但其中的 8 个字节 ce d2 ca c7 ba ba d7 d6对用 GBK 的大陆人,用 BIG5 的港澳台同胞,以及用 Latin-1 的欧洲人看来,看到的却是完全不同的文字。
明确概念 2: 如同我们都了解的A与x41等价一样。
GBK 编码下的const char str 我是汉字等价于const char str xcexd2xcaxc7xbaxbaxd7xd6当用 UTF-8 编码时,等价于const char str xe6x88x91xe6x98xafxe6xb1x89xe5xadx97注意:这个说法不全对,比如保存成带 BOM 的 UTF-8,用 cl 编译器时,汉字本身是 UTF-8 编码,但程序内保存时却是对应的 GBK 编码。
明确概念 3: QString 内部采用的是 Unicode。
QString 内部采用的是 Unicode,它可以同时存放 GBK 中的字符我是汉字BIG5中的字符扂岆荦趼 以及 Latin-1 中的字符×。
一个问题是,源代码中的这 8 个字节xcexd2xcaxc7xbaxbaxd7xd6,该怎么转换成 Unicode 并存到 QString 内?按照 GBK、BIG5、Latin-1 还是其他方式...在你不告诉它的情况下,它默认选择了 Latin-1,于是 8 个字符×的unicode 码被存进了 QString 中。
最终,8 个 Latin 字符出现在你期盼看到 4 中文字符的地方,所谓的乱码出现了QString 工作方式const char str 我是汉字QString a str其实很简单的一个问题,当你需要从窄字符串 char 转成 Unicode 的 QString字符串的,你需要告诉 QString 你的这串 char 中究竟是什么编码?GBK、BIG5、Latin-1理想情况就是:将 char 传给 QString 时,同时告诉 QString 自己的编码是什么:就像下面的函数一样,QString 的成员函数知道按照何种编码来处理 C 字符串QString QString::fromAscii const char str int size -1 QString QString::fromLatin1 const char str int size -1 QString QString::fromLocal8Bit const char str int size -1 QString QString::fromUtf8 const char str int size -1 单 QString 只提供了这几个成员函数,远远满足不了大家的需求,比如,在简体中文 Windows 下,local8Bit 是 GBK,可是有一个 char 串是 BIG5 或 Latin-2怎么办?那就动用强大的 QTextCodec 吧,首先 QTextCodec 肯定知道自己所负责的编码的,然后你把一个 char 串送给它,它就能正确将其转成 Unicode 了。
QString QTextCodec::toUnicode const char chars const可是这个调用太麻烦了,我就想直接QString a str或QString astr这样用怎么办?这样一来肯定没办法同时告诉 QString 你的 str 是何种编码了,只能通过其他方式了。
这也就是开头提到的QTextCodec::setCodecForCStringsQTextCodec::codecForNameGBKQTextCodec::setCodecForCStringsQTextCodec::codecForNameUTF-8设置 QString 默认采用的编码。
而究竟采用哪一个,一般来说就是源代码是 GBK,就用 GBK,源代码是 UTF-8 就用 UTF-8。
但有一个例外,如果你保存成了带 BOM的 UTF-8 而且用的微软的 cl 编译器,此时仍是 GBK。
上一篇:
java 记事本
下一篇:
论“十二五”期间的行政体制改革