编码?在VS下的理解。
preface: 参考文章:VS2019 编码问题,如何完美改为UTF-8_vs utf-8-CSDN博客 | 探究Visual Studio中的乱码问题_visual studio 英文乱码-CSDN博客
引入
关于字符的编码,有ANSI(也可以认为就是GBK,中国汉字用的编码),ASCII(仅支持2^8个字符),utf-8(全球统一编码)。不懂的可自行查阅:锟斤拷烫烫烫�ַ��ͨ?文字乱码频发 你该如何避免?带你探索乱码编码解码的前世今生_哔哩哔哩_bilibili|
在VS中文版,默认的字符编码格式就是GBK,当我们通过特殊的方法改成通用的utf-8时,却发生了匪夷所思的一幕。、
//文件存储的编码格式是 utf-8。
1 | #include <stdio.h> |
结果却是匪夷所思的 乱码。为什么会这样?
1 | #include <stdio.h> |
这样的程序运行的结果竟然是正常的?
正文
VS插件FileEncoding
问题一
VS中的三个字符集概念:
1.源码字符集
即源代码文本文件的字符集,NodePad++、记事本、VS Code这样类似的文本编辑器,可以打开源文件看一下你的字符集(文件编码)。
源代码文本文件是以二进制的形式存在硬盘里的,无论中文英文都一样,当你输入一个汉字后保存关闭,这个汉字就会按照你指定的字符集转换成二进制编码保存下去的,当你在以这个格式打开文件时候,就再按照你指定的字符集把二进制转回来。如果两次使用不同的字符集,也就会出现乱码了。
2.执行字符集
执行字符集决定了这行代码在编译器进行编译的时候,str存储的字节到底是什么,你可能会说源码字符集不是已经决定了这个”我”的二进制表示了么?没错,但是这个执行字符集就是让你在这里对它再解释一次。比如我源码字符集可能是UTF8的,但是我可以通过执行字符集来让最终str存储的是GBK的字节编码。
3.解析字符集
最终要还原显示这些二进制字节编码的时候,就需要用到它。比如通过printf()
把前面的str
显示到控制台时,这个printf()
就会按照解析字符集来解析这些字节编码,找到指定字符显示出来。比如下面的控制台输出编码。
简而言之,对于执行字符集,Visual Studio默认根据系统的Locale来决定执行字符集,一般大家都是Windows中文系统,Locale是中国,那么就是GBK编码。对于解析字符集,如果没有手动更改的话,Visual Studio的标准输入输出(printf,cout)到命令行也是根据系统Locael决定的,也就是GBK。
结论
由此,我们可以知道printf
中的汉字,实际上编译的时候用的是GBK方式,所以设定控制台输出为utf-8后 就无法正常显示了。
解决方法,一是添加下面的命令#pragma execution_character_set("utf-8")
;二是在前面添加u8
前缀
1 | //#pragma execution_character_set("utf-8") |
问题二
char是一个字符,用的是ASCII码,那它为何能够储存中文呢?或者说,按道理在gbk的编码格式下,char根本无法正常使用才对啊。
实际上,gbk和utf-8都兼容 ASCII码,也就是说,假如0在ASCII码中编译为0000,那再gbk中也是0000。所以英文能正常使用。那中文嘞?
我们深刻理解编码、解码原理。加咖啡
,占6字节,假设再gbk编码下为000….,那么char的作用,就是储存一个字节而已。然后,系统按照gbk的表,解码,从而正常显示。
所以,当我们把汉字、英文看作 一串二进制的数时,一切便合理起来。
1 | #include <stdio.h> |
还有,tchar,wchar_t,LPCSTR(long, *p, const, string)。