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

时间:2012-11-29 14:08:38

标签: c++ windows winapi visual-c++ character-encoding

当我有这样的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是什么?

2 个答案:

答案 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来指定代码页。