如果在C中有字符串,则可以在其中添加直接十六进制代码。
char str[] = "abcde"; // 'a', 'b', 'c', 'd', 'e', 0x00
char str2[] = "abc\x12\x34"; // 'a', 'b', 'c', 0x12, 0x34, 0x00
两个示例都在内存中有6个字节。现在,如果要在十六进制输入后添加值[a-fA-F0-9]
,则存在问题。
//I want: 'a', 'b', 'c', 0x12, 'e', 0x00
//Error, hex is too big because last e is treated as part of hex thus becoming 0x12e
char problem[] = "abc\x12e";
可能的解决方案是在定义后更换。
//This will work, bad idea
char solution[6] = "abcde";
solution[3] = 0x12;
这可行,但如果您将其设为const
,则会失败。
//This will not work
const char solution[6] = "abcde";
solution[3] = 0x12; //Compilation error!
如何在e
之后正确插入\x12
而不会触发错误?
我为什么要问?如果要将 UTF-8 字符串构建为常量,则必须使用字符的十六进制值,如果它大于ASCII表所能容纳的字符。
答案 0 :(得分:52)
使用3个八进制数字:
char problem[] = "abc\022e";
或拆分你的字符串:
char problem[] = "abc\x12" "e";
为什么这些工作:
与十六进制转义不同,标准定义了3位作为八进制转义的最大数量。
6.4.4.4字符常量
...
octal-escape-sequence: \ octal-digit \ octal-digit octal-digit \ octal-digit octal-digit octal-digit
...
hexadecimal-escape-sequence: \x hexadecimal-digit hexadecimal-escape-sequence hexadecimal-digit
字符串文字连接被定义为比文字转义字符转换更晚的转换阶段。
5.1.1.2翻译阶段
...
每个源字符集成员和转义序列的字符常量和 字符串文字转换为执行字符的相应成员 组;如果没有相应的成员,则转换为实施 - 除null(宽)字符以外的已定义成员。 8)
- 醇>
连接相邻的字符串文字标记。
答案 1 :(得分:18)
由于字符串文字在编译过程的早期是连接的,但在转义字符转换之后,你可以使用:
char problem[] = "abc\x12" "e";
虽然您可能更愿意完全分离以提高可读性:
char problem[] = "abc" "\x12" "e";
对于我们中间的语言律师,C11 5.1.1.2 Translation phases
(我的重点)涵盖了这一点:
转换了字符常量中的每个源字符集成员和 转义序列 ,并转换了 字符串文字 到执行字符集的相应成员;如果没有相应的成员,则将其转换为除null(宽)字符以外的实现定义的成员。
- 醇>
连接相邻的字符串文字标记。