2011-08-16 24 views
3

任何人都可以解釋爲什麼通用字符文字(例如「\ u00b1」)被編碼爲字符串作爲UTF-8?爲什麼以下打印加號/減號符號?打印通用字符

#include <iostream> 
#include <cstring> 
int main() 
{ 
    std::cout << "\u00b1" << std::endl; 
    return 0; 
} 

這與我當前的語言環境有關嗎?

回答

4

2.13.2。 [...]

5將通用字符名稱轉換爲名爲的字符集的執行字符集中的編碼 。如果沒有 這樣的編碼,則通用字符名稱被轉換爲實現定義的編碼。 [注意:在翻譯階段1中,每當在源文本中遇到實際擴展的 字符時,都會引入一個 通用字符名稱。因此,所有擴展的 字符都以通用字符名稱來描述。 但是,只要獲得相同的結果,實際的編譯器實現可以使用它自己的本地 字符集。 ]

2.2。 [...]執行字符集 的成員的值是實現定義的,並且任何其他成員都是 區域設置特定的。

簡而言之,您的問題的答案在您的編譯器文檔中。但是:

2.2。 2 /通用字符名稱 \ UNNNNNNNN指定的字符是ISO/IEC 10646中的字符短名稱爲NNNNNNNN的字符;由 universal-character-name \ uNNNN指定的字符是ISO/IEC 10646中短名稱的字符 爲0000NNNN的字符。如果通用字符名稱的 的十六進制值小於0x20或範圍爲0x7F-0x9F (含),或者通用字符名稱指定了基本源字符集中的字符 ,則該程序是格式錯誤的。

所以你保證你的名字被轉換成實現定義的編碼,可能是特定於語言環境的。

+1

謝謝。我現在在GNU文檔中看到執行字符集是由-fexec-charset設置的,默認是UTF-8。 –

1

\u00b1±符號,因爲無論區域設置如何,這都是正確的unicode表示形式。

您的代碼在ideone, see here

0

C++字符集

用C++的標準化工作,是非常有用的回顧一些包含在用於處理字符集的語言的機制。這可能看起來像一個非常簡單的問題,但有一些複雜性需要解決。

要考慮的第一個想法是C++中「基本源字符集」的概念。這被定義爲:

all ASCII printing characters 041 - 0177, save for @ $ ` DEL 

    space 

    horizontal tab 

    vertical tab 

    form feed 

    newline 

或總共96個字符。這些是用來組成C++源程序的字符。

某些國家字符集(如歐洲的ISO-646)使用其他字母中的某些字符位置。所以受影響的ASCII字符是:

[ ] { } | \ 

爲了解決這個問題,C++定義了可以被用來表示這些字符三字符序列:

[  ??(

    ]  ??) 

    {  ??< 

    }  ??> 

    |  ??! 

    \  ??/ 

    #  ??= 

    ^  ??' 

    ~  ??- 

三字符序列被映射到相應的基本源字符在編譯過程早期。

C++也有「替代令牌」的概念,可以用來代替其他令牌。令牌及其替代列表如下:

{  <% 

    }  %> 

    [  <: 

    ]  :> 

    #  %: 

    ##  %:%: 

    &&  and 

    |  bitor 

    ||  or 

    ^  xor 

    ~  compl 

    &  bitand 

    &=  and_eq 

    |=  or_eq 

    ^=  xor_eq 

    !  not 

    !=  not_eq 

另一個想法是「基本執行字符集」。這包括所有基本源字符集,以及警報,退格,回車和空值的控制字符。 「執行字符集」是基本執行字符集加上額外的實現定義字符。這個想法是,一個源字符集用於定義一個C++程序本身,而一個C++應用程序正在執行時使用一個執行字符集。

考慮到這個概念,可以在正在運行的程序中操作其他字符,例如來自西里爾文或希臘文的字符。字符常量可以用下列任何一種表示:

\137   octal 

    \xabcd   hexadecimal 

    \u12345678  universal character name (ISO/IEC 10646) 

    \u1234   -> \u000

這個表示法使用源字符集來定義執行集字符。通用字符名稱可用於標識符時(如字母)和字符文字:在您的本地C++編譯器

'\u1234' 

    L'\u2345' 

上述功能可能還不存在。在開發國際化應用程序時,它們非常重要。

+1

你的答案大部分與這個問題沒有任何關係,而且最多分散注意力。 –

+0

@Konrad Rudolph是一個完整的suportitive anser –

+0

其實答案是正確的。但是要想成爲有用的人,這是很長的路要走。 –

1

字符串文字例如"abcdef"是簡單的字節數組(類型const char[])。編譯器將其中的非ASCII字符編碼爲實現定義的內容。傳言說Visual C++使用當前Windows的ANSI代碼頁,並且GCC使用UTF-8,因此您可能在GCC上:)

因此,\uABCD在編譯時由編譯器解釋並轉換爲相應的編碼值。即它可以把一個或多個字節到字節數組:

sizeof("\uFE58z") == 3 // visual C++ 2010 
sizeof("\uFE58z") == 5 // gcc 4.4 mingw 

然而,如何cout將打印的字節數組,取決於區域設置。您可以通過std::ios_base::imbue()調用更改流的語言環境。

+2

爲什麼你有'z'? (誠​​實的問題) –