2011-04-21 24 views
0

我試圖在windows命令提示符下輸出以下字符:ュ(U + FF6D)。wcout不會寫寬字符到命令提示符

我能夠看到使用WriteConsoleW寫出字符。我也能夠看到字符,如果我使用WideCharToMultiByte使用CP_ACP代碼頁(chcp返回932:日語)。但是,當我嘗試在WriteConsoleW成功打印的相同字符串上使用常規wcout時,它會窒息。

當我執行setlocale(LC_ALL,「」)時,它會打印English_UnitedStates.1252(我安裝時的默認代碼頁)。

爲什麼wcout在其他人成功時失敗?

注:我重新啓動機器的系統區域設置更改爲日本

+2

你曾經調用'std :: wcout.imbue()'來改變'wcout'的代碼頁嗎? – ildjarn 2011-04-21 23:30:16

+0

工作。但是,當我重置系統區域設置時,爲什麼wcout的代碼頁不同?發表一個解釋,你會得到簡單的點。 – bogertron 2011-04-21 23:34:59

回答

2

C++ iostreams的默認語言環境始終是「C」語言環境。從C++ 03標準,§27.4.2.3/ 4:

locale getloc() const;

如果沒有語言環境已經充滿,在施工時間的全局C的副本++語言環境,locale(),實際上。

從§22.1.1.2/ 1-2:

locale() throw();

默認構造方法:目前全球區域的快照。

構造最後傳遞給locale::global(locale&)的參數的副本,如果它已被調用;否則,生成的構面具有與locale::classic()相同的虛函數語義。

從§22.1.1.5/ 4-6:

static const locale& classic();

的 「C」 語言環境。

返回:實現經典「C」語言環境語義的語言環境,等效於值locale("C")

注意:此語言環境,其構面及其成員函數不隨時間而改變。

作爲std::coutstd::wcout具有靜態存儲持續時間,它們保證main之前被初始化被調用,並且因此將總是具有在應用程序啓動的「C」語言環境;即在執行時沒有足夠的時間點,可以調用locale::global並更改std::coutstd::wcout的默認語言環境。因此,如果您想使用非默認代碼頁,則必須始終自己填充全局流。

+0

所以我想這是一個特定於Windows的問題。在我的應用程序中,我沒有在任何時候調用cout.imbue,但它仍然可以處理代碼頁字符。我是在假設(是假設邪惡的東西),wcout會灌輸相同的語言環境。 – bogertron 2011-04-22 00:02:43

0

wcout創建之前的任何代碼main執行。當您撥打setlocale時,wcout已經在那裏,準備好做它的事情。它不會嘗試跟蹤隨後可能對setlocale所做的更改,因此它將繼續使用默認值,而不是您使用setlocale設置的值。

+0

好的,這是有道理的,但如果我的機器啓動了一個能夠打印字符(U + FF6D)的語言環境,它具有映射字符到CP 932.我想我的問題是如何定義wcout的默認語言環境? – bogertron 2011-04-21 23:52:31

+0

@bogertron:我的回答解決了這方面的問題。 – ildjarn 2011-04-21 23:54:34