¿Cómo agregar correctamente escapes hexadecimales en un literal de cadena?

4 minutos de lectura

avatar de usuario
tilz0R

Cuando tiene una cadena en C, puede agregar código hexadecimal directo dentro.

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

Ambos ejemplos tienen 6 bytes en la memoria. Ahora el problema existe si quieres agregar valor [a-fA-F0-9] después de la entrada 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";

La posible solución es reemplazar después de la definición.

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

Esto puede funcionar, pero fallará, si lo pones como const.

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

Cómo insertar correctamente e después \x12 sin desencadenar error?


¿Por qué estoy preguntando? Cuando quieras construir UTF-8 cadena como constante, debe usar valores hexadecimales de carácter si es más grande de lo que puede contener la tabla ASCII.

  • Duplicado: stackoverflow.com/questions/35180528/…. Cerraré esa porque creo que las respuestas publicadas aquí son más completas, con el estándar citado dentro de la respuesta en lugar de en los comentarios.

    – Lundin

    10 de agosto de 2017 a las 12:41


avatar de usuario
usuario694733

Utilice 3 dígitos octales:

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

o divide tu cadena:

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

Por qué estos funcionan:

  • A diferencia de los escapes hexadecimales, el estándar define 3 dígitos como cantidad máxima para el escape 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
    
  • La concatenación de cadenas literales se define como una fase de traducción posterior a la conversión de caracteres de escape literales.

    5.1.1.2 Fases de traducción

    1. Cada miembro del conjunto de caracteres de origen y secuencia de escape en constantes de caracteres y literales de cadena se convierte en el miembro correspondiente del conjunto de caracteres de ejecución; si no hay ningún miembro correspondiente, se convierte en un miembro definido por la implementación que no sea el carácter nulo (ancho). 8)

    2. Los tokens de literales de cadena adyacentes se concatenan.

  • Una tercera alternativa es hacer todo explícitamente: char solution[] = {'a', 'b', 'c', 0x12, 'e', '\0'};

    – Lundin

    10 de agosto de 2017 a las 12:38

  • O incluso compensar la “cadena” de escapes por completo. "abc" "\x12" "e"; para mayor claridad.

    – chux – Reincorporar a Monica

    10 de agosto de 2017 a las 12:38

avatar de usuario
paxdiablo

Dado que los literales de cadena se concatenan al principio del proceso de compilación, pero después la conversión de caracteres escapados, simplemente puede usar:

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

aunque es posible que prefiera una separación completa para facilitar la lectura:

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

Para los abogados de idiomas entre nosotros, esto está cubierto en C11 5.1.1.2 Translation phases (mi énfasis):

  1. Cada miembro del conjunto de caracteres de origen y secuencia de escape en constantes de carácter y literales de cadena se convierte en el miembro correspondiente del conjunto de caracteres de ejecución; si no hay ningún miembro correspondiente, se convierte en un miembro definido por la implementación que no sea el carácter nulo (ancho).

  2. Los tokens de literales de cadena adyacentes se concatenan.

¿Por qué estoy preguntando? Cuando desee construir una cadena UTF-8 como constante, debe usar valores hexadecimales de caracteres que sean más grandes de lo que puede contener la tabla ASCII.

Bueno no. tu no tengo que. A partir de C11, puede prefijar su constante de cadena con u8que le dice al compilador que el carácter literal está en UTF-8.

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

(Por cierto, lo mismo es compatible con C++ 11)

  • La gente podría estar buscando los caracteres no imprimibles del 0 al 31 de la clásica tabla ASCII de 7 bits.

    – Lundin

    10 de agosto de 2017 a las 13:22

  • @Lundin ¿No deberían preferir omitir el carácter 0…?

    – Cia Pan

    10 de agosto de 2017 a las 21:05

  • @Damon C y C++ son lenguajes diferentes. El estándar C no es el mismo (lo busqué por su texto y no apareció). Puede usar constantes de caracteres universales, por ejemplo u8"\u12345678"porque barra invertida, u, 1 etc. están en el conjunto de caracteres de origen; sin embargo, es posible que el carácter Unicode indicado no esté en el conjunto de caracteres de origen. El código fuente solo puede contener caracteres del juego de caracteres de origen, que podría ser ASCII de 7 bits, por ejemplo (esto no está relacionado con el juego de caracteres de ejecución).

    –MM

    15 de agosto de 2017 a las 9:24


  • @Damon, esta es una pregunta de C, y el estándar C existe, literalmente no hay razón para involucrar a C++

    –MM

    15 de agosto de 2017 a las 10:21

  • Ya lo hice y expliqué en mi comentario anterior. universal-character-name está permitido porque todos los caracteres que componen tal cosa están en el conjunto de caracteres de origen básico, pero los caracteres Unicode pueden no estarlo. Está definido por la implementación de lo que está en el conjunto de caracteres fuente extendido y eso podría estar vacío.

    –MM

    15 de agosto de 2017 a las 12:32


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad