哪些编码是我的源string?

当我有这样的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 ++编译器如何决定哪个字符编码源文件?

如果开发人员使用“普通”文本文件默认为另一种单/多字节编码的机器,会发生什么?

我假设编码只是用于编译代码的机器上的一个问题? 也就是说,一旦构build了可执行文件,将静态string从固定的窄编码转换为Windows的UTF-16 wchar_t将始终产生相同的结果,而不pipe用户PC上的语言/语言环境如何。

对于宽文字,VC ++将始终生成UTF-16,而对于窄文字,VC ++将始终从源编码转换为在主机(运行编译器的系统)上设置的“非Unicode程序编码”。 所以只要VC ++能够正确识别出你将得到的源代码,UTF-16和非Unicode程序的编码。

为了确定源代码编码,VC ++检测所谓的物料清单。 它将识别UTF-16和UTF-8。 如果没有BOM,则假定源是使用非Unicode程序的系统编码进行编码的。

如果这导致使用了错误的编码,则编译器对字符和字符串文字执行的任何转换都将导致ASCII范围外的任何字符的值错误。


一旦程序被编译,那么是的,只要这些编译时间转换结束,语言环境将停止提供,因为数据是静态的。

编码可能对其他事情有影响,例如,如果您将其中一个字符串打印到控制台。 您将不得不执行适当的转换到任何控制台正在使用或确保控制台设置为接受您正在使用的编码。


请注意#pragma setlocale

#pragma setlocale只影响到宽文字的转换,而且它不是通过设置源编码,也不是通过改变宽执行编码。 坦率地说,它实际上是做的,令人震惊。 正如一个例子,下面的断言失败了

 #pragma setlocale(".1251") static_assert(L'Я' != L'ß', "wtf..."); 

如果您使用任何Unicode编码来源,则绝对应该避免这种情况。

语言规范只是说源字符以实现定义的方式映射。 您需要查阅所使用的编译器的文档,以查看该实现的定义。 例如,Microsoft Visual C ++使用#pragma setlocale指定代码页。