簡體   English   中英

在 C++ 源代碼中使用 Unicode

[英]Using Unicode in C++ source code

C++源代碼的標准編碼是什么? C++ 標准甚至對此有什么說明嗎? 我可以用 Unicode 編寫 C++ 源代碼嗎?

例如,我可以在評論中使用非 ASCII 字符,例如漢字嗎? 如果是這樣,是否允許使用完整的 Unicode 或只是 Unicode 的一個子集? (例如,那個 16 位的第一頁或它叫什么。)

此外,我可以將 Unicode 用於字符串嗎? 例如:

Wstring str=L"Strange chars: â Țđ ě €€";

C++ 中的編碼相當復雜。 這是我對它的理解。

每個實現都必須支持來自基本源字符集的字符 其中包括 §2.2/1(C++11 中的 §2.3/1)中列出的常見字符。 這些字符應該都適合一個char 此外,實現必須支持一種使用稱為universal-character-names的方式命名其他字符的方法,並且看起來像\￿\\Uffffffff並且可以用來指代 Unicode 字符。 它們的一個子集可用於標識符(在附件 E 中列出)。

這一切都很好,但是從文件中的字符到源字符(在編譯時使用)的映射是實現定義的。 這構成了所使用的編碼。 這是它的字面意思(C++98 版本):

如有必要,物理源文件字符以實現定義的方式映射到基本源字符集(為行尾指示符引入換行符)。 Trigraph 序列 (2.3) 被相應的單字符內部表示替換。 任何不在基本源字符集 (2.2) 中的源文件字符都將替換為指定該字符的通用字符名稱。 (實現可以使用任何內部編碼,只要源文件中遇到的實際擴展字符,以及源文件中作為通用字符名稱(即使用 \\uXXXX 符號)表示的相同擴展字符,都被處理等價。)

對於 gcc,您可以使用選項-finput-charset=charset更改它。 此外,您可以更改用於在運行時重新設置值的執行字符。 正確的選項是-fexec-charset=charset for char(默認為utf-8 )和-fwide-exec-charset=charset (默認為utf-16utf-32取決於wchar_t的大小) .

據我所知,C++ 標准沒有說明源代碼文件編碼。

通常的編碼是(或曾經是)7 位 ASCII——一些編譯器(例如 Borland 的)會拒絕使用高位的 ASCII 字符。 沒有技術原因不能使用 Unicode 字符,如果你的編譯器和編輯器接受它們——大多數現代基於 Linux 的工具,以及許多更好的基於 Windows 的編輯器,處理 UTF-8 編碼沒有問題,盡管我不確定微軟的編譯器會不會。

編輯:看起來微軟的編譯器會接受 Unicode 編碼的文件,但有時也會在 8 位 ASCII 上產生錯誤:

warning C4819: The file contains a character that cannot be represented
in the current code page (932). Save the file in Unicode format to prevent
data loss.

除了 litb 的帖子,MSVC++ 也支持 Unicode。 我知道它從 BOM 中獲取 Unicode 編碼。 它絕對支持像int (*♫)();這樣的代碼int (*♫)(); const std::set<int> ∅; 如果你真的很喜歡代碼混淆:

typedef void ‼; // Also known as \u203C
class ooɟ {
    operator ‼() {}
};

這里有兩個問題在起作用。 第一個是 C++ 代碼(和注釋)中允許使用的字符,例如變量名。 第二個是字符串和字符串文字中允許使用的字符。

如前所述,C++ 編譯器必須為代碼和注釋中允許的字符支持非常受限的基於 ASCII 的字符集。 在實踐中,這個字符集在一些歐洲字符集(尤其是一些沒有幾個字符——比如方括號——可用)的歐洲鍵盤上工作得不是很好,所以二合字母和三合字母的概念是介紹。 目前,許多編譯器接受的字符集不止這個字符集,但沒有任何保證。

對於字符串和字符串文字,C++ 有寬字符和寬字符串的概念。 但是,該字符集的編碼未定義。 實際上,它幾乎總是 Unicode,但我認為這里沒有任何保證。 寬字符串文字看起來像 L“字符串文字”,這些可以分配給 std::wstring 的。


C++11 添加了對 Unicode 字符串和字符串文字的顯式支持,編碼為 UTF-8、UTF-16 大端、UTF-16 小端、UTF-32 大端和 UTF-32 小端。

對於字符串編碼,我認為您應該使用\\u\u003c/strong>符號,例如:

std::wstring str = L"\u20AC"; // Euro character

還值得注意的是,C++ 中的寬字符並不是真正的 Unicode 字符串。 它們只是較大字符的字符串,通常為 16 位,但有時為 32 位。 這是實現定義的,但是,IIRC 你可以有一個 8 位wchar_t你不能真正保證它們的編碼,所以如果你試圖做一些像文本處理這樣的事情,你可能最想要一個 typedef適合您的 Unicode 實體的整數類型。

C++1x 以 UTF-8 編碼字符串文字 ( u8"text" )、UTF-16 和 UTF-32 數據類型 ( char16_tchar32_t IIRC) 以及相應的字符串常量 ( u"text"U"text" )。 盡管沒有\\uxxxx\\Uxxxxxxxx常量指定的字符編碼仍然是實現定義的(並且沒有對文字之外的復雜字符串類型的編碼支持)

在這種情況下,如果您收到 MSVC++ 警告 C4819,只需將源文件編碼更改為“UTF-8 with Bom”。

GCC 4.1 不支持,但 GCC 4.4 支持,最新的 Qt 版本使用 GCC 4.4,所以使用“UTF-8 with Bom”作為源文件編碼。

AFAIK 這不是標准化的,因為您可以將任何類型的字符放在寬字符串中。 您只需要檢查您的編譯器是否設置為 Unicode 源代碼以使其正常工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM