[英]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-16
或utf-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_t
和char32_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.