为什么使用 UTF8 在字符串文本中字符串化欧元符号不会生成 UCN
Why does stringizing an euro sign within a string literal using UTF8 not produce an UCN?
规范说在编译的第 1 阶段
不在基本源字符集 (2.3( 中的任何源文件字符都将替换为指定该字符的通用字符名称。
在第 4 阶段,它说
执行预处理指令,扩展宏调用
在第 5 阶段,我们有
字符文本或字符串文本中的每个源字符集成员,以及字符文本或非原始字符串文本中的每个转义序列和通用字符名称,都将转换为执行字符集的相应成员
对于#
运营商,我们有
在字符文本或字符串文本(包括分隔
"
字符(的每个"
和字符之前插入
字符。
因此,我进行了以下测试
#define GET_UCN(X) #X
GET_UCN("€")
使用UTF-8的输入字符集(与我的文件的编码匹配(,我期望#X
操作的以下预处理结果:""\u20AC""
。GCC,Clang和boost.wave不会将€
转换为UCN,而是产生""€""
。我觉得我错过了什么。你能解释一下吗?
这只是一个错误。 §2.1/1 说关于阶段 1,
(实现可以使用任何内部编码,只要在源文件中遇到实际的扩展字符,并且在源文件中表示为通用字符名称的相同扩展字符(即使用 \uXXXX 表示法(得到等效处理。
这不是注释或脚注。C++0x 为原始字符串文本添加了一个例外,如果有的话,这可能会解决您手头的问题。
该程序清楚地演示了故障:
#include <iostream>
#define GET_UCN(X) L ## #X
int main() {
std::wcout << GET_UCN("€") << 'n' << GET_UCN("u20AC") << 'n';
}
http://ideone.com/lb9jc
由于两个字符串都很宽,因此如果编译器无法解释输入多字节序列,则需要将第一个字符串损坏为多个字符。在您给出的示例中,完全缺乏对 UTF-8 的支持可能会导致编译器盲目地回显序列。
"字符文本或非原始字符串文本中的通用字符名称将转换为执行字符集的相应成员">
曾经是
"或字符文本和字符串文本中的通用字符名称转换为执行字符集的成员">
也许你需要一个未来版本的 g++。
我不确定您从哪里获得翻译阶段 1 的引用 — C99 标准在 §5.1.1.2/1 中对翻译阶段 1 这样说:
因此,在这种情况下,欧元字符 €(在 UTF-8如有必要,物理源文件多字节字符以实现定义的方式映射到源字符集(为行尾指示符引入换行符(。三元组序列被相应的单字符内部表示所取代。
中表示为多字节序列 E2 82 AC(映射到执行字符集,该字符集恰好也是 UTF-8,因此其表示形式保持不变。 它不会被转换为通用字符名称,因为,嗯,没有什么说它应该。
我怀疑你会发现欧元符号不满足条件Any source file character not in the basic source character set
所以你引用的其余文本不适用。
使用您喜欢的二进制编辑器打开测试文件,并检查用于表示欧元登录GET_UCN("€")
- 如何通过 JNI 将 C 字符串表情符号传递给 Java
- 字符串到无符号字符
- 尝试将字符串从文件读取到无符号字符向量中
- 将字符串转换为无符号字符数组/字节数组
- 如何将字符串转换为无符号字符数组
- 在Arduino中将字符串转换为(逗号分隔的十六进制)字符串到无符号字符数组
- 如何使用istream_iterator将无符号字符向量转换为字符串?
- 将 unicode 字符串与 c ++ 符号进行比较?
- 如何从字符数组(不是字符串数组)中删除符号
- 提升不良词法强制转换:将字符串转换为无符号长整型时,无法将源类型值解释为目标
- 将字符串变量分配给无符号字符变量
- 将'\x00\x00\x00'格式的字符串转换为无符号字符数组
- 为C++字符串中的特殊符号 (") 赋予文字含义的有效C++方法
- 以 Null 结尾的字符串的"NULL"或" "符号是否存储在文件中?
- 提取或(甚至更好)更改 char* 字符串的第一个符号
- 将无符号字符 * 转换为十六进制字符串
- 如何对包含数字和符号的字符串进行排序?
- C++如何将无符号字符数组转换为字符串?
- C++字符串表示中将无符号字符数组转换为长(或长长)
- 将数学符号存储到字符串 c++ 中