任何人都可以解釋爲什麼通用字符文字(例如「\ u00b1」)被編碼爲字符串作爲UTF-8?爲什麼以下打印加號/減號符號?打印通用字符
#include <iostream>
#include <cstring>
int main()
{
std::cout << "\u00b1" << std::endl;
return 0;
}
這與我當前的語言環境有關嗎?
任何人都可以解釋爲什麼通用字符文字(例如「\ u00b1」)被編碼爲字符串作爲UTF-8?爲什麼以下打印加號/減號符號?打印通用字符
#include <iostream>
#include <cstring>
int main()
{
std::cout << "\u00b1" << std::endl;
return 0;
}
這與我當前的語言環境有關嗎?
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 (含),或者通用字符名稱指定了基本源字符集中的字符 ,則該程序是格式錯誤的。
所以你保證你的名字被轉換成實現定義的編碼,可能是特定於語言環境的。
\u00b1
是±
符號,因爲無論區域設置如何,這都是正確的unicode表示形式。
您的代碼在ideone, see here。
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'
上述功能可能還不存在。在開發國際化應用程序時,它們非常重要。
你的答案大部分與這個問題沒有任何關係,而且最多分散注意力。 –
@Konrad Rudolph是一個完整的suportitive anser –
其實答案是正確的。但是要想成爲有用的人,這是很長的路要走。 –
字符串文字例如"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()
調用更改流的語言環境。
爲什麼你有'z'? (誠實的問題) –
謝謝。我現在在GNU文檔中看到執行字符集是由-fexec-charset設置的,默認是UTF-8。 –