Como adicionar corretamente escapa hexadecimal em uma string literal?

Quando você tem uma string em C, você pode adicionar o código hexadecimal direto dentro dela.

char str[] = "abcde"; // 'a', 'b', 'c', 'd', 'e', 0x00 char str2[] = "abc\x12\x34"; // 'a', 'b', 'c', 0x12, 0x34, 0x00 

Ambos os exemplos têm 6 bytes na memory. Agora o problema existe se você quiser adicionar valor [a-fA-F0-9] após a input hexadecimal.

 //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"; 

A solução possível é replace após a definição.

 //This will work, bad idea char solution[6] = "abcde"; solution[3] = 0x12; 

Isso pode funcionar, mas irá falhar, se você colocar como const .

 //This will not work const char solution[6] = "abcde"; solution[3] = 0x12; //Compilation error! 

Como inserir corretamente e depois de \x12 sem acionar o erro?


Por que estou perguntando? Quando você quer construir uma string UTF-8 como constante, você tem que usar valores hexadecimais de caractere se ele for maior que a tabela ASCII pode conter.

Use 3 dígitos octal:

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

ou divida sua string:

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

Por que estes trabalhos:

  • Ao contrário das fugas hexadecimais, o padrão define 3 dígitos como quantidade máxima para a fuga octal.

    6.4.4.4 Constantes de caracteres

     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 
  • Concatenação literal de cadeia é definida como uma fase de conversão posterior à conversão de caractere de escape literal.

    5.1.1.2 Fases da tradução

    1. Cada membro do conjunto de caracteres de origem e a sequência de escape em constantes de caracteres e literais de cadeia são convertidos no membro correspondente do conjunto de caracteres de execução; se não houver um membro correspondente, ele será convertido em um membro definido pela implementação diferente do caractere nulo (grande). 8)

    2. Os tokens literais de cadeia adjacente são concatenados.

Como literais de string são concatenados no início do processo de compilation, mas depois da conversão de caracteres de escape, você pode simplesmente usar:

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

embora você possa preferir a separação total para facilitar a leitura:

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

Para os advogados de idiomas entre nós, isso é coberto em C11 5.1.1.2 Translation phases (minha ênfase):

  1. Cada membro do conjunto de caracteres de origem e a sequência de escape em constantes de caracteres e literais de cadeia são convertidos no membro correspondente do conjunto de caracteres de execução; se não houver um membro correspondente, ele será convertido em um membro definido pela implementação diferente do caractere nulo (grande).

  2. Os tokens literais de cadeia adjacente são concatenados.

Por que estou perguntando? Quando você quer construir uma string UTF-8 como constante, você tem que usar valores hexadecimais de caractere maiores que a tabela ASCII pode conter.

Bem não. Você não precisa . A partir de C11, você pode prefixar sua constante de string com u8 , que informa ao compilador que o literal do caractere está em UTF-8.

 char solution[] = u8"no need to use hex-codes á駵"; 

(A mesma coisa é suportada pelo C ++ 11 também, a propósito)