我的源字符串是哪种编码?

Mar*_* Ba 3 c++ windows winapi character-encoding visual-c++

当我有这样的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)?
Run Code Online (Sandbox Code Playgroud)

如果这是我们的cpp文件的(隐式)编码,我可以一直假设Win-1252吗?Visual-C++编译器如何确定源文件所在的字符编码?

如果开发人员使用"正常"文本文件默认为另一个单/多字节编码的计算机,会发生什么?

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

bam*_*s53 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...");
Run Code Online (Sandbox Code Playgroud)

如果您对源使用任何Unicode编码,那么绝对应该避免.