繁体   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