我无法理解c ++标准中的含义:
任何不在基本源字符集中的源文件字符(2.3) 由指定它的通用字符名称替换 特征。 (实现可以使用任何内部编码,这么久 作为源文件中遇到的实际扩展字符,和 在源文件中表示的相同扩展字符为 通用字符名称(即使用\ uXXXX表示法)是 处理等效,除非这个替换在a。中被还原 原始字符串文字。)
据我了解,如果编译器看到charcter不在基本字符集中,它只是用这种格式的字符序列替换它'\ nNNNNN'或'\ UNNNNNNNN'。但我不知道如何获得这个NNNN或NNNNNNNN。 所以这是我的问题:如何进行转化?
答案 0 :(得分:3)
请注意前面的句子:
物理源文件字符以实现定义的方式映射到基本源字符集(如果需要,引入行尾指示符的换行符)。
也就是说,它完全取决于编译器如何实际解释构成文件的字符或字节。在进行此解释时,必须确定哪个物理字符属于基本源字符集,哪些不属于。如果一个角色不属于某个角色,那么它将被替换为通用角色名称(或者至少,效果是就像那样)。
这一点是将源文件减少到一小组字符 - 基本源字符集中只有96个字符。任何不在基本源字符集中的字符都已替换为\
,u
或U
,以及一些十六进制数字(0
- F
)。< / p>
通用字符名称是以下之一:
\uNNNN
\UNNNNNNNN
每个N
是十六进制数字。这些数字的含义在§2.3中给出:
通用字符名
\UNNNNNNNN
指定的字符是ISO / IEC 10646中字符短名称为NNNNNNNN
的字符;通用字符名\uNNNN
指定的字符是ISO / IEC 10646中的字符短名称为0000NNNN
的字符。如果通用字符名称的十六进制值对应于代理代码点(在0xD800
-0xDFFF
范围内),则该程序格式不正确。
ISO / IEC 10646标准在Unicode之前发起并定义了通用字符集(UCS)。它为字符分配了代码点,并指定了应如何编码这些代码点。然后,Unicode Consortium和ISO小组联合起来处理Unicode。 Unicode标准规定的不仅仅是ISO / IEC 10646(算法,功能字符规范等),但两种标准现在保持同步。
因此,您可以将NNNN
或NNNNNNNN
视为该字符的Unicode代码点。
例如,请考虑源文件中包含以下内容的行:
const char* str = "Hellô";
由于ô不在基本源字符集中,因此该行内部转换为:
const char* str = "Hell\u00F4";
这将得到相同的结果。
您的代码中只有某些部分允许使用通用字符名称:
答案 1 :(得分:2)
但我不知道如何获得这个NNNN或NNNNNNNN。所以这是我的问题:如何进行转换?
映射是实现定义的(例如§2.3脚注14)。例如,如果我将以下文件保存为Latin-1:
#include <iostream>
int main() {
std::cout << "Hallö\n";
}
在OS X上使用g++
进行编译,运行后得到以下输出:
Hell�
...但如果我把它保存为UTF-8,我就会得到这个:
Hellö
因为GCC假定UTF-8作为我系统上的输入编码。
其他编译器可能会执行不同的映射。
答案 2 :(得分:1)
因此,如果您的文件被称为Hello°¶.c
,那么在内部使用该名称时,编译将是如果我们这样做:
cout << __FILE__ << endl;
编译器会将Hello°¶.c
翻译为Hello\u00b0\u00b6.c
。
但是,当我用g++
尝试此操作时,它不会这样做......
但汇编程序输出包含:
.string "Hello\302\260\302\266.c"