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

相關問題