Microsoft Windows提供了几个函数来查询当前代码页: GetACP
, GetConsoleOutputCP
, GetConsoleCP
。
他们返回不同的值。 例如,在我的机器上, GetACP
返回1252,而GetConsoleOutputCP
和GetConsoleCP
返回437。
(我们也可以在命令行上运行chcp
并获得437)
此问题的背景是从Visual Studio C ++的错误消息:
error C2855: command-line option '/source-charset' inconsistent with precompiled header error C2855: command-line option '/execution-charset' inconsistent with precompiled header
这些错误发生在预编译头文件使用不同的默认代码页面而不是使用它们的CPP文件(无论什么原因)时。
从MSDN文档 :
如果找不到字节顺序标记,则假定源文件使用当前用户代码页编码,除非使用/ source-charset选项指定字符集名称或代码页。
所以我想弄清楚他们引用哪个代码页, GetACP
或其他的返回的代码页…
ANSI和OEM代码页由系统引导时加载的系统区域设置决定。 它们被映射到每个进程中,作为PEB字段AnsiCodePageData
和OemCodePageData
。 ntdll.dll中的运行时库有许多与这些字符串类型一起工作的函数,例如RtlAnsiStringToUnicodeString
和RtlOemStringToUnicodeString
。
在Windows API中以A结尾的函数是ANSI,但文件系统函数可以通过SetFileApisToOEM
切换到OEM。 控制台API默认为OEM以兼容传统应用程序,并且可以通过SetConsoleCP
和SetConsoleOutputCP
将其更改为另一个代码页。 chcp.com(或mode.com)调用这些函数,但不允许将输入缓冲区和屏幕缓冲区设置为不同的代码页。
如果ANSI代码页是1252,那么OEM代码页不一定是437.这仅在美国区域设置。 大多数使用1252作为ANSI代码页的西方语言环境将使用850作为OEM代码页。
表示使用用户代码页的应用程序可能不是指系统ANSI或OEM代码页。 相反,它可以调用,例如, GetLocaleInfoEx
查询LOCALE_IDEFAULTANSICODEPAGE
或LOCALE_IDEFAULTCODEPAGE
的LOCALE_NAME_USER_DEFAULT
语言环境。
由于传统原因,命令控制台使用不同的代码页。 在控制台上运行的程序通常是为DOS编写的,而字符集包含了在这种情况下很有用的线条字符等内容。 在具有本地Windows应用程序的图形环境中,扩展可用字符更为重要,因为直接绘制线条而不是使用字体进行模拟。
默认代码页是由Windows将使用的语言决定的。 不同的语言需要不同的字符,单个代码页不足以适应欧洲语言使用的所有字符。 例如,您可以在某些中欧和东欧地区找到代码页1250 。