# VS编码问题
我们安装的VS默认的编码格式是GBK2312,这一点如果用VIM的命令行模式去查`:set fileencoding` 可能查不到,结果是`fileencoding=` 。
一般默认新建一个项目后,在项目属性的【预处理器】位置处会写一些宏,这里会有个默认宏定义是 `_MBCS` 多字符编码格式。
现在将VS的默认编码格式设置为UTF-8(VS2017版本,其他版本都是差不多的)。在【工具】->【自定义】->【命令】->【菜单栏|文件】->【添加命令】->【文件】->【高级保存选项】,这样文件下的高级保存选项就显示出来了,在保存文件时,选择以UTF-8的编码格式保存,这样就完成了。
每次保存文件时都要注意以什么样的编码格式保存,当然也可以安装 `ForceUTF-8` 这个插件来达到自动设置编码格式保存的效果。【工具】->【扩展和更新】->【联机】->【安装插件ForceUTF-8】。当然在搜索到的插件中有两个,一个是`ForceUTF-8(No BOM)` 和 `ForceUTF-8(with BOM)` 。
## No BOM和With BOM
UTF-8编码的文件可以分为without BOM和BOM两种格式。
何谓BOM? `“EF BB BF”` 这三个字节就叫BOM,BOM的全称叫做"Byte Order Mark". 在UTF-8文件中常用BOM来表明这个文件是UTF-8文件, 而BOM的本意是在UTF-16中用来表示高低字节序列的。在字节流之前有BOM表示采用低字节序列(低字节在前面),而UTF-8不用考虑字节序列,所以其实有无BOM都可以。UTF-8以字节为编码单元,没有字节序的问题。UTF-16以两个字节为编码单元,在解释一个UTF-16文本前,首先要弄清楚每个编码单元的字节序。例如收到一个“奎”的Unicode编码是594E,“乙”的Unicode编码是4E59。如果我们收到UTF-16字节流“594E”,那么这是 “奎”还是“乙”?
如果文件保存时,选择了使用BOM,那么就可能会出现headers already sent的问题。因为Web服务器软件可能不认识BOM,所以就把BOM的两个特殊字节当做字符发送给浏览器了。这时再调用session_start()等函数,就会出现headers already sent的问题。所以解决此问题最根本的方法就是在保存UTF-8编码的文件时,不要使用BOM。
微软的记事本Word等只能正确打开含BOM的UTF8文件,然而UltraEdit却恰恰相反,会把BOM UTF-8文件误认为ascii编码。UTF-8的BOM是 EFBBBF,因为UE载入UTF-8文件会转成Utf16,上述的EFBBBF 在Utf16中是FFFE(Unicode-LE的BOM),UltraEdit不认识BOM又加多一個BOM,所以有2个FFFE。文件就被它破坏了。
因为文本是有编码的,比如中文有常用的GBK编码,日文有Shift_JIS编码,如果没有历史遗留问题,强烈建议使用标准的UTF-8编码,所有语言使用同一种编码,既没有冲突,又被所有平台所支持。
使用Windows要特别注意:
千万不要使用Windows自带的记事本编辑任何文本文件。原因是Microsoft开发记事本的团队使用了一个非常弱智的行为来保存UTF-8编码的文件,他们自作聪明地在每个文件开头添加了`0xefbbbf`(十六进制)的字符,你会遇到很多不可思议的问题,比如,网页第一行可能会显示一个“?”,明明正确的程序一编译就报语法错误,等等,都是由记事本的弱智行为带来的。建议你下载Notepad++代替记事本,不但功能强大,而且免费!记得把Notepad++的默认编码设置为UTF-8 without BOM即可。
UTF-8withoutbom 指的是没有BOM头的文件,在linux中一般均使用没有没有BOM头的文件。
编码问题对于全英文书写的人来说就不那么重要,但是我们一般在注释处会写上中文,所以最好都是以UTF-8的编码格式保存。