2

Microsoft Windows提供了几种查询当前代码页的功能: GetACPGetConsoleOutputCPGetConsoleCP为什么ANSI代码页和控制台代码页是不同的?

它们返回不同的值。例如,我的机器上,GetACP回报1252,而GetConsoleOutputCPGetConsoleCP返回437

(我们也可以运行在命令行上chcp并获得437)

  • 为什么Windows提供不同的代码页控制台和非控制台?
  • 这些代码页是如何确定每台机器?
  • 同一台机器上的代码页之间的关系是什么?控制台和非控制台代码页之间是否存在关联?具有代码页1252的机器是否总是拥有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或其他返回的其中一个代码页...

回答

5

的ANSI和OEM代码页是由系统语言环境是确定当系统启动时加载。它们被映射到每个过程中,作为PEB字段AnsiCodePageDataOemCodePageData。 ntdll.dll中的运行时库具有很多可以处理这些字符串类型的函数,例如RtlAnsiStringToUnicodeStringRtlOemStringToUnicodeString

在Windows API中以A结尾的函数是ANSI,但文件系统函数可以通过SetFileApisToOEM切换到OEM。控制台API默认为OEM以兼容传统应用程序,并可通过SetConsoleCPSetConsoleOutputCP更改为其他代码页。 chcp.com(或mode.com)调用这些函数,但它不允许将输入缓冲区和屏幕缓冲区设置为不同的代码页。

如果ANSI代码页是1252,那么OEM代码页不一定是437.仅在美国区域设置。大多数使用1252作为ANSI代码页的西方语言环境将使用850作为OEM代码页。

一个声称使用用户代码页的应用程序可能不是指系统ANSI或OEM代码页。相反,它可以呼叫,例如GetLocaleInfoEx来查询LOCALE_NAME_USER_DEFAULT区域设置的LOCALE_IDEFAULTANSICODEPAGELOCALE_IDEFAULTCODEPAGE

+2

对于下流者来说,如果你没有解释就冷静下来,那就是你的特权。但至少给出一点反馈让我知道什么是错的更有帮助;如果我有改进答案的方法,或者您的理由足够重要,我应该删除此答案。 – eryksun

+0

downvoter可能是拖钓。没有解释,这个问题也被低估了。现在你提到的最后一件事让我感到困惑。除了ANSI和OEM之外,我们还有其他代码页吗?根据[此MSDN页面](https://msdn.microsoft.com/en-us/library/windows/desktop/dd373761(v = vs.85).aspx)'LOCALE_IDEFAULTANSICODEPAGE'返回ANSI代码页和'LOCALE_IDEFAULTCODEPAGE '返回OEM代码页。它们与'GetACP','GetConsoleCP'等返回的代码页有什么不同? –

+0

大多数Windows语言环境都定义了ANSI和OEM代码页。用户的区域设置不一定与系统区域设置相同。您可以使用控制面板中的区域应用更改用户区域设置(即“格式”)。 'GetLocaleInfoEx'将在为'LOCALE_IDEFAULTANSICODEPAGE'和'LOCALE_IDEFAULTCODEPAGE'(OEM)返回的值中动态地反映。但是,更改系统区域设置(区域 - >管理)需要重新启动以查看'GetACP()'和'GetOEMCP()'中反映的更改。 – eryksun

2

由于传统原因,命令控制台使用不同的代码页。在控制台上运行的程序通常是为DOS编写的,字符集包含了在此上下文中很有用的线条字符等内容。在具有本机Windows应用程序的图形环境中,扩展可用字符更为重要,因为直接绘制线条而不是用字体模拟。

默认代码页由Windows将使用的语言决定。不同的语言需要不同的字符,并且单个代码页不足以适应欧洲语言使用的所有字符。例如,您会在中欧和东欧某些地区找到code page 1250

相关问题