如何正确地将十六进制转义添加到字符串文字中?

时间:2017-08-10 11:44:02

标签: c c99

如果在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表所能容纳的字符。

2 个答案:

答案 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翻译阶段

         

    ...

         
        
    1. 每个源字符集成员和转义序列的字符常量和   字符串文字转换为执行字符的相应成员   组;如果没有相应的成员,则转换为实施 -   除null(宽)字符以外的已定义成员。 8)

    2.   
    3. 连接相邻的字符串文字标记。

    4.   

答案 1 :(得分:18)

由于字符串文字在编译过程的早期是连接的,但转义字符转换之后,你可以使用:

char problem[] = "abc\x12" "e";

虽然您可能更愿意完全分离以提高可读性:

char problem[] = "abc" "\x12" "e";

对于我们中间的语言律师,C11 5.1.1.2 Translation phases(我的重点)涵盖了这一点:

  
      
  1. 转换了字符常量中的每个源字符集成员和 转义序列 ,并转换了 字符串文字 到执行字符集的相应成员;如果没有相应的成员,则将其转换为除null(宽)字符以外的实现定义的成员。

  2.   
  3. 连接相邻的字符串文字标记。

  4.