2010-03-17 22 views
4

如何找出當前的C++字符集?如何查找C++中當前的字符集是什麼?

在一個控制檯應用程序(操作系統)我與

(int)mystring[a] 

越來越負值對於一些字符(比如äöüé),這令我感到奇怪。我期待值在127和256之間。

那麼在C++中有什麼像GetCharset()或SetCharset()?

+2

什麼類型是mystring? – 2010-03-17 13:45:23

+0

你期望什麼價值?您可以獲取當前的語言環境,然後找出與該語言環境和編碼對應的字形ID(鬆散地說)。最有可能的是,字形ID大於int可以在系統上保存的大小。此外,如果'mystring'的類型是'wstring',那麼你需要考慮多字節字符編碼。 – dirkgently 2010-03-17 13:48:48

+0

@Daniel Daranas mystring是一個std :: string – Stef 2010-03-17 13:49:57

回答

5

這取決於你如何看待你手頭的價值。 char可以被簽名(例如在Windows上),或者像在其他一些系統上一樣被簽名。所以,你應該做的就是打印這個值作爲無符號來得到你所要求的。

C++直到現在都是字符集不可知的。特別是對於Windows控制檯,您可以使用:GetConsoleOutputCP

+0

我正在回答這個問題,因爲你回答了第一個問題。其餘的奧祕仍然是一個謎...它不是關於有符號或無符號整數的...... – Stef 2010-03-17 21:07:54

1

請看std::numeric_limits<char>::min()max()。或者如果你不喜歡打字,或者你需要一個整數常量表達式,則可以使用CHAR_MINCHAR_MAX

如果CHAR_MAX == UCHAR_MAXCHAR_MIN == 0那麼字符是無符號的(如您所期望的)。如果CHAR_MAX != UCHAR_MAXCHAR_MIN < 0它們已簽名(如您所見)。

在標準3.9.1/1中,確保沒有其他可能性:「...一個普通字符可以採用與有符號字符或無符號字符相同的值;哪一個是實現定義的「。

這告訴你char是簽名還是未簽名,這就是讓你感到困惑的原因。你當然不能調用任何東西來修改它:即使編譯器有改變它的方法,它也可以從程序的POV中被燒入編譯器中(GCC當然可以:-fsigned-char-funsigned-char)。

處理此問題的常用方法是,如果您要投charint,首先將其投射到unsigned char。所以在你的例子中,(int)(unsigned char)mystring[a]。這確保您獲得一個非負值。

它實際上並沒有告訴你什麼字符集你的實現用於char,但我不認爲你需要知道這一點。在Microsoft編譯器上,答案基本上就是常用的字符編碼「ISO-8859-mutter-mutter」。這意味着具有7位ASCII值的字符由該值表示,而該範圍之外的值不明確,並且將由控制檯或其他收件人根據收件人的配置方式進行解釋。 ISO拉丁語1除非另有說明。

正確地說,字符解釋的方式是特定於語言環境的,並且語言環境可以使用一大堆東西進行修改和詢問,直到C++標準的結尾,這個標準我個人從未經歷過,也不能建議;-)

請注意,如果字符集的效果與控制檯使用的字符集不匹配,那麼您可能會遇到麻煩。但我認爲這與您的問題是分開的:字符是否可以是負數與charsets無關,只是char是否被簽名。

0

,該標準提供了唯一出示擔保是基本字符集的成員:

2.2字符集

基本執行字符集 和基本執行wide-字符 集應包含基本源字符集的所有成員 , 加上控制字符表示 警報,退格和回車, 加空字符(分別爲, 空寬字符),其 表示具有全零位。對於 每個基本執行字符集, 成員的值應爲 非負數並且不同於另一個 。在源和 執行基本字符集中, 上面的每個字符的值在 以上的小數位數列表中應爲 ,其值大於前一個的值 。執行字符集 和執行寬字符集 分別是基本執行 字符集和基本執行 寬字符集的超集。執行 字符集的成員的 值是 實現定義的,和任何 附加成員是區域特異性

此外,類型char應該成立:

3.9.1基本類型

將對象聲明爲字符(char)應足夠大以存儲 實現的基本 字符集的任何成員。

因此,沒有保證你會得到正確的值,你提到的字符。但是,請嘗試使用unsigned int來保存此值(對於所有實際用途,如果要打印它們/傳遞給它,使用簽名類型永久保存值爲char永遠不會有意義)。

+0

「使用有符號類型來保存char值永遠沒有意義」不幸的是,所有用於處理字符的C標準庫函數都是這樣做的。 – 2010-03-17 14:03:47

+0

他們這樣做,但你最好使用'toupper((unsigned char)c);'where int c = getchar();'等等...... – dirkgently 2010-03-17 14:13:49

+0

同意(請參閱我的回答)。你必須在某個時候引入一個無符號類型,我所討論的是它是否應該是'unsigned int'來保存該值(完全合理的所有其他都是相等的),或者'unsigned char'作爲腳本中的墊腳石通往'int'(C-library-idiom)的路。 – 2010-03-17 14:21:44

0

字符默認情況下通常是簽名的。 試試這個。

cout << (unsigned char) mystring[a] << endl; 
相關問題