当我有这样的C ++代码时:
std::string narrow( "This is a narrow source string" );
std::string n2( "Win-1252 (that's the encoding we use for source files): ä,ö,ü,ß,€, ..." );
// What encoding should I pass to Win32's `MultiByteToWideChar` function
// to convert these string to a propoer wchar_t (= UTF-16 on Windows)?
如果这是我们的cpp文件的(隐式)编码,我可以一直假设Win-1252吗? Visual-C ++编译器如何确定源文件所在的字符编码?
如果开发人员使用“正常”文本文件默认为另一种单/多字节编码的计算机,会发生什么?
我认为编码只是用于编译代码的机器上的一个问题?也就是说,一旦构建了可执行文件,将静态字符串从固定的窄编码转换为Windows的UTF-16 wchar_t将始终产生相同的结果,而不管用户PC上的laguage / locale是什么?
答案 0 :(得分:5)
对于宽文字,VC ++将始终生成UTF-16,对于窄文字,VC ++将始终从源编码转换为主机上设置的“非Unicode程序编码”(运行编译器的系统) 。因此,只要VC ++正确识别您将获得的源编码,UTF-16和非Unicode程序的编码。
确定源编码VC ++检测所谓的BOM。它将识别UTF-16和UTF-8。如果没有BOM,则它假定使用系统的非Unicode程序编码对源进行编码。
如果这导致使用了错误的编码,那么编译器对字符和字符串文字执行的任何转换都将导致ASCII范围之外的任何字符的值都是错误的。
一旦程序被编译然后是,就这些编译时转换而言,语言环境将停止,因为数据是静态的。
编码可能对其他事情很重要,例如,如果您将其中一个字符串打印到控制台。您要么必须对控制台正在使用的任何内容执行适当的转换,要么确保将控制台设置为接受您正在使用的编码。
关于#pragma setlocale
#pragma setlocale
仅影响到宽文字的转换,它既不通过设置源编码也不通过更改宽执行编码来实现。坦率地说,它实际上做的是令人恐惧。作为示例,以下断言失败:
#pragma setlocale(".1251")
static_assert(L'Я' != L'ß', "wtf...");
如果您对源使用任何Unicode编码,则绝对应该避免使用。
答案 1 :(得分:3)
语言规范仅表示源字符以实现定义的方式映射。您需要查阅正在使用的编译器的文档,以了解该实现的定义。例如,Microsoft Visual C ++使用#pragma setlocale
来指定代码页。