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 docs:
如果未找到字节顺序标记,则假定源文件已编码 除非您指定字符集,否则使用当前用户代码页 使用/ source-charset选项命名或代码页。
所以我试图找出他们引用的代码页,GetACP
或其他代码页返回的代码页......
答案 0 :(得分:8)
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_NAME_USER_DEFAULT
或LOCALE_IDEFAULTANSICODEPAGE
的{{1}}区域设置。
答案 1 :(得分:2)
由于遗留原因,命令控制台使用不同的代码页。在控制台上运行的程序通常是为DOS编写的,字符集包括在此上下文中有用的线条图字符等内容。在具有本机Windows应用程序的图形环境中,扩展可用字符更为重要,因为直接绘制线条而不是用字体模拟。
默认代码页由Windows将使用的语言决定。不同的语言需要不同的字符,单个代码页不足以适合欧洲语言使用的所有字符。例如,您会在某些中欧和东欧地区使用code page 1250。
答案 2 :(得分:0)
每台机器如何确定这些代码页?
查看此表National Language Support (NLS) API Reference
或查询您的注册表:
C:\>reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage /v OEMCP
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage
OEMCP REG_SZ 850
C:\>reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage /v ACP
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage
ACP REG_SZ 1252