做优化网站注意什么,优秀茶叶网站设计,建设银行官网首页 网站,无锡网站制作多少钱此问题很常见#xff0c;然而网上关于此问题的分析大多不够深刻#xff0c;甚至有错误#xff1b;加之Qt5又更改了一些编码策略#xff0c;而很多文章并未提及版本问题#xff0c;或是就算提了#xff0c;读者也不重视。这些因素很容易让读者产生误导。今日我彻底研究透了… 此问题很常见然而网上关于此问题的分析大多不够深刻甚至有错误加之Qt5又更改了一些编码策略而很多文章并未提及版本问题或是就算提了读者也不重视。这些因素很容易让读者产生误导。今日我彻底研究透了这个问题在此记录。 环境Qt 4.8.7, Qt Creator 4.2.2, MSVC 2015
Qt 4.8.7 MSVC 的中文乱码问题实际上有两层原因。
第一层MSVC 不识别无 BOM 的 UTF-8
Qt Creator 默认源代码文件编码是无BOM的UTF-8而MSVC编译器会误认为这是本地多字节字符集MBCS编码对于简中地区即GBK代码页936。
解决方法1推荐Qt Creator选项—文本编辑器—文件编码—UTF8 BOM——如果编码是UTF8则添加—确定。解决方法2Qt Creator选项—文本编辑器—文件编码—默认编码—GBK—确定。
注意修改以上两种方法提及的设置后Qt Creator并不会自动修改已保存的文件的编码或BOM。我们需要修改一下含中文的文件重新CtrlS保存这样才能将这些设置应用于这些文件。
第二层QString 构造函数默认假定的文本编码不正确
我们代码中的字符串特别是用于测试这个乱码问题的字符串一般都是C样式的即用一对双引号包围的const char []类型字符串字面量如 Hello World 。然而 Qt 里很多函数的参数要求的字符串类型都是 QString我们填入这种C样式字符串时就会有个隐式转换转为QString类型其实也就是QString这个构造函数在帮我们转换
explicit QString::QString(const char* ch) 然而const char*类型只表明了这个字符串是多字节字符集却没指明是哪一种他可能是GBK, UTF-8等等甚至可能是跟咱这边八竿子打不着的西欧语言字符集Latin-1ISO-8859-1。不加声明的话MSVC默认我们的字符串字面量是本地多字节字符集MBCS即GBK编码如下图左侧“标题title”文本所示情况。而如果在这种C样式字符串的引号前加上“u8”二字则MSVC就会认为此字符串是UTF-8编码如下图右侧“文本text”文本所示情况。 MSVC在我们有或没有声明的情况下判断出了此字符串的编码后对此字符串进行编码也就是将它们转换为二进制的字节数据传给QString的构造函数。
注意①即使在上一层问题的解决中我们选择了保留UTF-8加上BOM供MSVC识别以上所述MSVC对C样式字符串的编码的解析方式仍然成立。他不会因为你的源码文件是UTF-8编码就将其中的这种字符串优先视为UTF-8。所以上一层问题你选择了哪种解决方法对这一层问题是没有影响的。 ②“u8”标记只是给MSVC编译器的提示MSVC处理后不管是加了u8还是没加一律变成const char[]这样的字节数组。也就是说有没有u8QString的构造函数是不知道的看不见的。他只知道传进来了一个const char* 类型。
传给QString的构造函数后QString要解码这些二进制数据也就是将它们映射到可显示我们能看懂的字符上。由于这些数据不能体现编码他就要猜。咱当然希望他猜是GBK啦但是事与愿违Qt库毕竟不是中国人写的。他默认猜成西欧语言字符集Latin-1如图这就会导致我们在代码里写了些汉字却显示出一堆拉丁字母甚至音标。这也是为何在没有QString参与的情况下只解决第一层问题就好了例如控制台窗口的std::cout而在需要把const char*转换成QString时就又会出问题。 那么解决思路已经很明显了。要么修改它的设置让他猜成GBK或UTF-8要么明明白白的告诉他我们的字符串是啥编码使用 QString::fromXXX 函数。
解决方法1推荐在 QApplication 对象创建前将“C样式字符串的编码(CodecForCStrings)”设为UTF-8并在每个含中文的字符串字面量的前导引号前加上u8二字如QString str(u8这是中文);。设置“C样式字符串的编码”的方法是在程序的入口点main函数中最开始的位置加上图中这句代码别忘了加头文件
QTextCodec::setCodecForCStrings(QTextCodec::codecForName(UTF-8)); 解决方法2 跟方法1一样修改“C样式字符串的编码”但设为本地多字节字符集MBCS一般是GBK代码中的字符串字面量不加“u8”如QString str(这是中文);。具体方法和上条类似不再赘述但main函数中加的那句代码改为
QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
解决方法3 在每个字符串字面量的前导引号前加上u8并用 QString::fromUtf8() 包裹如图 解决方法4字符串字面量的前导引号前不加u8并用 QString::fromLocal8Bit() 包裹如图 依次解决以上两层问题后中文就不再乱码了。再次强调本文只针对 Qt 4.8.7 MSVC2015 环境提供问题原理和解决方案Qt5就不一样了说不定微软也会在未来的MSVC中添加对无BOM的UTF-8文件的识别。那时问题的解决将简单很多。
szx0427 作于 2024/07/17