C ++源代码的标准编码是什么? C ++标准是否甚至对此有所说明?我可以用Unicode编写C ++源代码吗?
例如,我可以在评论中使用非ASCII字符,例如中文字符吗?如果是这样,是允许完全Unicode还是只是Unicode的一个子集? (例如,16位第一页或其他任何名称。)
此外,我可以将Unicode用于字符串吗?例如:
Wstring str=L"Strange chars: â Țđ ě €€";
答案 0 :(得分:34)
C ++中的编码非常复杂。这是我对它的理解。
每个实现都必须支持基本源字符集中的字符。这些包括§2.2/ 1中列出的常见字符(C ++ 11中的§2.3/ 1)。这些字符都应该合为一个char
。此外,实现必须支持使用名为universal-character-names
的方式命名其他字符的方法,并且看起来像\uffff
或\Uffffffff
,并且可用于引用Unicode字符。它们的一个子集可用于标识符(在附录E中列出)。
这很好,但是从文件中的字符到源字符(在编译时使用)的映射是实现定义的。这构成了所使用的编码。这就是字面意思(C ++ 98版):
物理源文件字符是 映射,在实现定义中 方式,基本来源角色 设置(引入换行符 对于终端指标)如果 必要。 Trigraph序列(2.3) 被相应的替换 单字符内部 表示。任何源文件 字符不在基本来源中 字符集(2.2)被替换为 通用字符名称 点燃那个角色。 (一个 实施可以使用任何内部 编码,只要是实际的 遇到的扩展字符 源文件,和扩展名相同 在源文件中表示的字符 作为通用字符名称(即 使用\ uXXXX表示法,是 等价处理。)
对于gcc,您可以使用选项-finput-charset=charset
进行更改。此外,您可以在运行时更改用于表示值的执行字符。适当的选项是-fexec-charset=charset
用于char(默认为utf-8
)和-fwide-exec-charset=charset
(默认为utf-16
或utf-32
,具体取决于wchar_t
)。
答案 1 :(得分:9)
据我所知,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.
答案 2 :(得分:9)
除了litb的帖子,MSVC ++也支持Unicode。据我所知,它从BOM中获取Unicode编码。它绝对支持int (*♫)();
或const std::set<int> ∅;
等代码
如果你真的陷入代码晦涩:
typedef void ‼; // Also known as \u203C
class ooɟ {
operator ‼() {}
};
答案 3 :(得分:6)
这里有两个问题。第一个是C ++代码(和注释)中允许的字符,例如变量名。第二个是字符串和字符串文字中允许的字符。
如上所述,C ++编译器必须支持一个非常受限制的基于ASCII的字符集,用于代码和注释中允许的字符。在实践中,这个字符集对于一些欧洲字符集(特别是一些没有几个字符的欧洲键盘 - 如方括号 - 可用)效果不佳,因此有向图和三字符的概念是介绍。许多编译器目前接受的不仅仅是这个字符集,但没有任何保证。
对于字符串和字符串文字,C ++具有宽字符和宽字符串的概念。但是,该字符集的编码未定义。在实践中它几乎总是Unicode,但我认为这里没有任何保证。宽字符串文字看起来像L“字符串文字”,可以将它们分配给std :: wstring。
C ++ 11增加了对Unicode字符串和字符串文字的明确支持,编码为UTF-8,UTF-16大端,UTF-16小端,UTF-32大端和UTF-32小端。
答案 4 :(得分:3)
对于字符串编码,我认为您打算使用 \ u 表示法,例如:
std::wstring str = L"\u20AC"; // Euro character
答案 5 :(得分:2)
值得注意的是,C ++中的宽字符并不是真正的Unicode字符串。它们只是较大字符的字符串,通常为16,但有时为32位。这是实现定义的,但IIRC你可以拥有一个8位wchar_t
你对它们中的编码没有真正的保证,所以如果你试图做一些像文本处理这样的事情,你可能会想要一个将Unicode定义为最适合Unicode实体的整数类型。
C ++ 1x以UTF-8编码字符串文字(u8"text"
),UTF-16和UTF-32数据类型(char16_t
和{{1}的形式提供额外的unicode支持} IIRC)以及相应的字符串常量(char32_t
和u"text"
)。不使用U"text"
或\uxxxx
常量指定的字符的编码仍然是实现定义的(并且文字之外的复杂字符串类型没有编码支持)
答案 6 :(得分:2)
在这种情况下,如果您收到MSVC ++警告C4819,只需将源文件编码更改为“UTF-8 with Bom”。
GCC 4.1不支持此功能,但GCC 4.4支持,最新的Qt版本使用GCC 4.4,因此请使用“UTF-8 with Bom”作为源文件编码。
答案 7 :(得分:0)
AFAIK它没有标准化,因为你可以在宽字符串中放置任何类型的字符。 您只需检查您的编译器是否设置为Unicode源代码,以使其正常工作。