2020.11.27 最后终于把这玩意里理解明白了,可能是翻译引起的理解差异吧。微软对此做出的解释:

对于vs编译器来说,有两个概念:

源字符集

执行字符集

对于vs2010 sp1-VS2015,引入指令#pragma execution_character_set("utf-8"),这只是将执行字符集设为UTF-8,然而源码字符集仅仅支持UTF-16 little bom、UTF-16 big、UTF-8 with BOM,你的文件格式UTF-8它就不支持,自己又去转换了,所以必定乱码,想不乱码,必须源码文件格式保存UTF-8 BOM (VS文件格式中叫 Unicode (UTF-8带签名))或者 简体中文格式 (linux等别的平台不支持);
);

在VS2015版本(Visual Studio 2015 Update 2)及其之后,微软放弃了上面的编译指令,新增编译选项/utf-8,只需要这一个命令就将源码字符集和执行文件字符集都指定为UTF-8,所以文件格式并不重要了,一个编译执行命令,文件编码格式UTF-8 BOMUTF-8、 简体中文格式三个都不会乱码了,当然优选UTF-8跨平台换编译器等都支持 ;

//vs2015 updater2以后以下两个编译命令等同于这一个命令 /utf-8

/source-charset:utf-8     源码字符集设为utf-8

/execution-charset:utf-8   执行字符集设为UTF-8


//两个基础概念

UTF-8 BOM  == Unicode (UTF-8带签名) 

UTF-8 == Unicode UTF-8无签名     //linux等平台默认支持此。

搞清楚以上这几个概念,再去看微软官方文档,便一目了然了。

https://docs.microsoft.com/en-us/cpp/preprocessor/execution-character-set?view=msvc-160

方法如下:

文件编码格式方法

结论:

1、vs2015 updater2-vs2019,只在vs版本下开发,想保持兼容性,文件编码格式建议采用UTF-8 BOM最省事,vs商店有插件ForceUTF8 (with BOM);

2、需要跨平台、库、算法涉及到跨平台、linux、换编译器,文件编码格式建议UTF-8,只能手动设置;

3、vs2010 sp1-vs2015 ,别想了,只能用UTF-8 BOM!


2020.11.26重新思考后,查看了,微软官方文档:

vs编辑器可以区分utf-8和utf-8 bom等,可编译器不认账,如果你不是这三个中的一个UTF-16 little bom、UTF-16 big、UTF-8 with BOM它就自做主张按默认处理,那你要么编译中文乱码要么qt的ui中文乱码。

https://docs.microsoft.com/en-us/previous-versions/xwy0e8f2(v=vs.140)?redirectedfrom=MSDN

也可以看看此试验,作者写的很详细:

https://blog.csdn.net/qq_33154343/article/details/78686075?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~sobaiduend~default-1-78686075.nonecase&utm_term=qt%20%E4%B8%AD%E6%96%87%E6%B3%A8%E9%87%8A%E9%80%A0%E6%88%90%E7%BC%96%E8%AF%91%E4%B8%8D%E9%80%9A%E8%BF%87&spm=1000.2123.3001.4430


2020.11.25  对编码格式报错产生疑问,为什么文件编码格式utf-8 vs2010就报错?明明QT默认就是这个格式?……

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

我先找一个例子,比如:"中文" 的 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)

// utf8 no bom
// 文件中包含不能在当前代码页(936)中表示的字符
#include <stdio.h>int main() {const char* str = "中文";for(int i = 0; i < sizeof(str); ++i) {printf("0x%x ", str[i]&0xFF);}return 0;// Output:// 0xe4 0xb8 0xad 0xe6
}

输出是:0xe4 0xb8 0xad 0xe6。
感觉好像是对的。

但是,先别急:VC编译时输出了一条警告信息:
utf8_no_bom.cpp : warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。
请将该文件保存为 Unicode 格式以防止数据丢失。

潜台词就是,你这个代码有GBK不能表示的字符,请用Unicode方式保存。
VC根本就没把 代码(utf8_no_bom.cpp) 当作UTF8,VC只是把它作为GBK处理罢了。

那为什么又输出了正确的结果呢?

因为 VC 把 (utf8_no_bom.cpp) 当作 GBK,而编译时也要转换为本地编码(也是GBK)。因此,UTF8编码的 "中文",被VC当作编码GBK编码的 "0xe4 0xb8 0xad 0xe6" 的字符串处理了(肯定不是"中文"含义了)。

VC已经不知道 "0xe4 0xb8 0xad 0xe6" 是对应 "中文" 字面值了。

但是在GBK(实际是无BOM的UTF8)转GBK的过程中,发现了一些UTF8编码的字符并不是GBK能表达的合理方式,因此就出现了那个C4819编译警告。

2. 再看带BOM的UTF8是怎么处理的 (utf8_with_bom.cpp)

// utf8 with bom
#include <stdio.h>int main() {const char* str = "中文";for(int i = 0; i < sizeof(str); ++i) {printf("0x%x ", str[i]&0xFF);}return 0;// Output:// 0xd6 0xd0 0xce 0xc4
}

编译没有警告,但是输出有问题:0xd6 0xd0 0xce 0xc4。

源文件明明是 UTF8 编码的格式"0xe4 0xb8 0xad 0xe6",
怎么变成了 "0xd6 0xd0 0xce 0xc4" (这个是GBK编码)?

这就是VC私下干的好事:它自作聪明的将UTF8源代码转换为GBK处理了!

VC为何要做这样蠢事?

原因是为了兼容老的VC版本。
因为以前的VC不能处理UTF8,都是用本地编码处理的。

3. 在看看真的GBK是怎么处理的 (gbk.cpp)

// gbk
#include <stdio.h>int main() {const char* str = "中文";for(int i = 0; i < sizeof(str); ++i) {printf("0x%x ", str[i]&0xFF);}return 0;// Output:// 0xd6 0xd0 0xce 0xc4
}

没有编译错误,输出也和源代码一致:"0xd6 0xd0 0xce 0xc4"。

因为源文件就是GBK,cl在编译时GBK转化为GBK,没有改变字符串。

只是,现在很多人不想用GBK了(因为只能在中国地区用,不能表示全球字符)。

------

到这里,可以初步小结一下:

1. VC编辑器和VC编译器是2个概念,VC编辑器支持UTF8并不能表示VC编译器也支持UTF8
2. VC编辑器从2008?开始支持带BOM的UTF8(不带BOM的暂时没戏,因为会本地编码冲突)
3. VC编译器从2010开始也可以支持UTF8了(虽然支持方式很不优雅)

------

继续前面的测试,

看看VC2010编译器是怎么支持带BOM的UTF8的 (utf8_with_bom_2010.cpp)

// utf8 with bom (VC2010), 下面这句是重点!
#pragma execution_character_set("utf-8")#include <stdio.h>int main() {const char* str = "中文";for(int i = 0; i < sizeof(str); ++i) {printf("0x%x ", str[i]&0xFF);}return 0;// Output:// 0xe4 0xb8 0xad 0xe6
}

没有编译错误,输出也和源代码一致:"0xe4 0xb8 0xad 0xe6"。

UTF8编码,UTF8输出。完美!

------

回到 Qt5 的中文输出问题。

Qt默认支持 VS2010/MinGW/Gcc 等编译器,而它们现在都已经真正支持UTF8了。

当然,VS2010 对UTF8的支持会入侵代码(#pragma execution_character_set("utf-8"))。

看看Qt官方论坛别人是怎么说的:
http://qt-project.org/forums/viewthread/17617

Nothing special need to do, it will works by default.
If the exec-charset of your your compiler is UTF-8.

简单的说,从Qt5开始,源代码就是默认UTF8编码的。

当然,VC2010编辑器对带BOM的UTF8也是认识,只可惜VC2010编译器根本不认识!

在继续看官方论坛的回复:

You can write a simple example like this#include <QApplication>
#include <QLabel>#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endifint main(int argc, char *argv[])
{QApplication a(argc, argv);QLabel label("ąśćółęńżź");label.show();return a.exec();
}If other people can reproduce your problem, you can file a bug.

vs2010 qt中文乱码 最终版相关推荐

  1. Qt中文乱码解决思路

    最近项目中遇到不少的Qt中文乱码的问题,主要原因是客户的需求比较多,Qt版本有用4的版本的也有用5的版本,并且还有windows与linux跨平台的需求. 经常出现个问题是windows的解决了,源代 ...

  2. 解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)——ubuntu环境设置默认是utf-8,文件编码可使用Encodersoft批量转换

    解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)--ubuntu环境设置默认是utf-8,文件编码可使用Encodersoft批量转换 参考文章: (1)解决Qt中文乱码以及汉字编码的问题(U ...

  3. Qt中文乱码原因及解决方案

    本文主要分析了基于windows系统msvc2013编译器的Qt中文乱码. 概念 字库表:是一个系统支持的文字,符号,数字的集合. 编码字符集(字符集):我们平时所说的字符集就是这个,计算机以二进制的 ...

  4. 彻底解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)

    尊重作者,支持原创,如需转载,请附上原地址:https://blog.csdn.net/libaineu2004/article/details/19245205 一.Qt Creator环境设置 1 ...

  5. QT中文乱码解决思路和方法汇总

    QT中文乱码解决思路和方法 中文编码一律使用QString::fromLocal8Bit()接口,原因是为了支持QT4版本.QStringLiteral()方法也可以使用,它是支持QT5版本的: CP ...

  6. QT中文乱码解决方法2

    转载自:http://blog.163.com/seven_7_one/blog/static/162606412201032955449489/ QT中文乱码的解 2010-04-29 17:54: ...

  7. Qt中文乱码解决办法

    目录 一.解决方法: 1. QT4版本 2. QT5版本 二.QString 为什么会乱码呢 三.tr的使用 一.解决方法: 1. QT4版本 中文乱码解决办法是在main.cpp文件加入: #inc ...

  8. Qt中文乱码--使用Unicode万国码解决

    需求 Qt界面开发过程中可能使用到多个语言的字符.需要解决乱码问题. API介绍 Qt 提供类:QTextCodec Class,用来支持各种编码协议,支持: ISO 2022-JP ISO 8859 ...

  9. linux下Qt中文乱码问题

    找了一天的中文乱码解决方案 虽然直接对程序设置: QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK")); Q ...

最新文章

  1. Serializer序列化使用
  2. IP、子网的详述 ——IP分类、网关地址,子网掩码、子网作用
  3. 谋定5G+工业互联网-陈肇雄:经信研究体系化应用部署规划
  4. 如何在SAP Cloud for Customer里自定义query
  5. easyphp环境配置
  6. ERROR: Unrecognized command line argument: #39;use#39;
  7. NYOJ 擅长排列的小明 II---Problem B
  8. 使用nginx作为代理实现动静分离
  9. extremeComponents资料
  10. Oracle视图(View)----------------数据库中虚拟的表
  11. 《第五项修炼——学习型组织的艺术与实务》读后感
  12. Python骚操作:Python控制Excel实现自动化办公!
  13. linux图形界面bind dns,在linux上使用BIND建立DNS服务器
  14. 标准的镜头质量评测方法——MTF(Modulation Transfer Function)
  15. 2018省赛第九届蓝桥杯真题C语言B组第六题题解 递增三元组
  16. 将excel(xls/xlsx)转换成csv文件
  17. 基于iOS平台配置免费离线语音识别功能-OpenEars
  18. Mysql中 begin..end使用遇到的坑
  19. 如何用Astra主题免费版建外贸网站
  20. c++语言截取字符串,详解C++ string常用截取字符串方法

热门文章

  1. 从Q4财报,看有道如何实现从在线教育“迷途”中脱身?
  2. nginx php默认首页,iis、apache、nginx设置默认首页index.html方法图解 电脑维修技术网...
  3. linux启用root用户,Ubuntu 下启用root账号与修改密码
  4. 微型计算机课程介绍,微机原理及应用课程教学大纲教案
  5. java this$0_java中this$0的含义及用法
  6. ssm访问html页面,SSM实现未登录无法访问页面
  7. 2015年职称计算机考试大纲,2015年职称计算机考试photoshop练习题6
  8. python 关于排序的问题
  9. Python基础教程:函数名本质
  10. Python字符串和正则表达式中的反斜杠(‘\‘)问题