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.
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
…
-
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)
-
Los tokens de literales de cadena adyacentes se concatenan.
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):
-
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).
-
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 u8
que 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)
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