由于VC2005的fstream不支持中文文件名问题,查了一些Unicode 资料,后来定位在VC2005如何对char和w_char 类型的字符串进行编码,发现
这篇文章最好《字符集与C/C++源文件编译生成乱弹》(http://zyxhome.org/wp/i18n/cset-loale-cpp-source-build-talk/),将结果摘录如下:
对 char字符串的解码:
实验结果:
-
MinGW GCC 4.4.0
源代码 内存中的字符串 可执行文件中的字串常量 写入的文件 GBK GBK GBK GBK UCS-2 LE (BOM) 编译出错 UCS-2 LE 编译出错 UTF-8 (BOM) UTF-8 UTF-8 UTF-8 UTF-8 UTF-8 UTF-8 UTF-8 -
Linux GCC 4.3.2
源代码 内存中的字符串 可执行文件中的字串常量 写入的文件 GBK GBK GBK GBK UCS-2 LE (BOM) 编译出错:不识别 BOM(FF FE),且源代码字符处理出错 UCS-2 LE 编译出错:源代码字符处理出错 UTF-8 (BOM) 编译出错:不识别 BOM(EF BB BF) UTF-8 UTF-8 UTF-8 UTF-8 -
VC8 cl 14.00.50727.42
源代码 内存中的字符串 可执行文件中的字串常量 写入的文件 GBK GBK GBK GBK UCS-2 LE (BOM) GBK GBK GBK UCS-2 LE GBK GBK GBK UTF-8 (BOM) GBK GBK GBK UTF-8 UTF-8 UTF-8 UTF-8
对w_char字符串的解码:
实验结果:
-
MinGW GCC 4.4.0
源代码 内存中的字符串 可执行文件中的字串常量 写入的文件 GBK 编译出错:无法将源代码中字符量转换到 UCS UCS-2 LE (BOM) 编译出错:不识别 BOM(FF FE),且源代码字符处理出错 UCS-2 LE 编译出错:源代码字符处理出错 UTF-8 (BOM) UCS-2 LE UCS-2 LE UCS-2 LE UTF-8 UCS-2 LE UCS-2 LE UCS-2 LE -
Linux GCC 4.3.2
源代码 内存中的字符串 可执行文件中的字串常量 写入的文件 GBK 编译出错:无法将源代码中字符量转换到 UCS UCS-2 LE (BOM) 编译出错:不识别 BOM(FF FE),且源代码字符处理出错 UCS-2 LE 编译出错:源代码字符处理出错 UTF-8 (BOM) 编译出错:不识别 BOM(EF BB BF) UTF-8 UCS-4 LE UCS-4 LE UCS-4 LE -
VC8 cl 14.00.50727.42
源代码 内存中的字符串 可执行文件中的字串常量 写入的文件 GBK UCS-2 LE UCS-2 LE UCS-2 LE UCS-2 LE (BOM) UCS-2 LE UCS-2 LE UCS-2 LE UCS-2 LE UCS-2 LE UCS-2 LE UCS-2 LE UTF-8 (BOM) UCS-2 LE UCS-2 LE UCS-2 LE UTF-8 UCS-2 LE (Wrong) UCS-2 LE (Wrong) UCS-2 LE (Wrong)
当用 VC8 编译不带 BOM 的 UTF-8 源文件时,虽然可以生成可执行程序,但是其中对 UCS 字符的编码出现了错误,在上表中用 Wrong 表示,其表现为:超出 ASCII 之外的字符变为另外奇怪的字符,即没有将源代码中的 UTF-8 字符串 "这是ABC 123汉字" 正确转换成 UCS-2 编码。原因是:当使用不带 BOM 的 UTF-8 文件时,是没有办法从“表象”上区分它究竟是 UTF-8 还是别的 Native ANSI 字符集编码,只能按照应用特定的优选编码来解析字符,而 VC8 编译器会优选系统配置的 Native ANSI 字符集作为解析字符集,因为是简体中文 Windows 所以这个是 GBK 字符集,编码错误就是因为 VC8 编译器把实际为 UTF-8 编码的字符当做 GBK 编码向 UCS-2 转换造成的。另外,VC8 有个特殊的 #pragma setlocale 预编译指示,用来指示源文件的编码。
======================================================================================================
结论:
1、w_char少用
从上面文章的表格中可以看出,想要程序夸平台,对于w_char,无论源代码采用何种格式,Linux 和VC8都无法得到同样的解码(linux只能正确解码UTF8格式的源文件,VC8对UTF8解码错误,即使解码正确,VC8是UCS2也与Linux的UCS4不同)
2、对char,用GBK或UTF8格式的源文件
由于还没了解透彻MBCToWidechar这类函数对UTF8的支持程度,最好用GBK。