c++ - 我的源字符串采用哪种编码?

标签 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)?

如果 Win-1252 是我们的 cpp 文件的(隐式)编码,我是否可以始终假定它是 Win-1252? Visual-C++ 编译器如何决定源文件的字符编码?

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

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

最佳答案

注意:由于编写了以下答案,VC++ 为源代码和执行字符集编码添加了额外的选项。 See here .


对于宽文字 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 编码,绝对应该避免这种情况。

关于c++ - 我的源字符串采用哪种编码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13627571/

相关文章:

c++ - 初始值设定项列表的模板替换错误

c++ - 适用于足球经理等数据驱动游戏的语言和数据库

c++ - 在 C 中使用 TSS 和 TrouSerS 创建背书 key

windows - SetConsoleScreenBufferInfoEx ...错误?

c - Windows 命令提示符如何处理连续的 CTRL + C (SIGINT) 信号?

c - LVCOLUMN.cchTextMax 和 LVITEM.cchTextMax 的用途是什么?

c++ - Rcpp:通过引用将行附加到数据框

Python:在 Windows 上打开和读取远程文本文件

c++ - 如何停止在所有桌面上显示 C/C++ WINAPI 窗口?

python - 如何使用 Python 查看 Windows 注册表的更改