¿Cuál es la codificación predeterminada para cadenas C?

6 minutos de lectura

avatar de usuario
plumenador

Sé que las cadenas C son char[] con un ‘\0’ en el último elemento. Pero, ¿cómo se codifican los caracteres?

Actualización: Encontré este enlace genial que habla sobre muchos otros lenguajes de programación y sus convenciones de codificación: Enlace

avatar de usuario
Nietzche-jou

Todo lo que dice el estándar al respecto es que obtienes al menos los 52 caracteres del alfabeto latino en mayúsculas y minúsculas, los dígitos del 0 al 9, los símbolos ! " # % & ' ( ) * + , - . / : ; < = > ? [ \ ] ^ _ { | } ~y el carácter de espacio, y los caracteres de control que representan el tabulador horizontal, el tabulador vertical, el salto de página, la alerta, el retroceso, el retorno de carro y la nueva línea.

Lo único que dice sobre la codificación numérica es que todo lo anterior cabe en un byte, y que el valor de cada dígito después del cero es uno mayor que el valor del anterior.

La codificación real probablemente se herede de la configuración regional. Probablemente algo compatible con ASCII.

  • Supongo que la configuración regional también se puede configurar en el compilador. Acabo de enterarme de la opción -finput-charset de gcc (gcc.gnu.org/onlinedocs/cpp/Invocación.html). El valor predeterminado parece ser UTF8. No es de extrañar que pudiera imprimir UTF8Strings.

    – Plumenador

    22 de octubre de 2010 a las 11:15


  • ¿El estándar también dice algo sobre los valores ordinales de los alfabetos?

    – Plumenador

    22 de octubre de 2010 a las 11:25

  • @Plumenator: No. Ni siquiera hay un requisito de que 'A' < 'B'.

    –Bart van Ingen Schenau

    22 de octubre de 2010 a las 13:29

  • @Plumenator: La única garantía sobre strcmp es que el valor de salida corresponde al valor numérico de los caracteres en la cadena. No dice nada sobre los mapas de resultados con el alfabeto.

    –Oliver Charlesworth

    22 de octubre de 2010 a las 13:38

avatar de usuario
freskoma

Una cadena c es más o menos una secuencia de bytes. Eso significa que no tiene una codificación bien definida, podría ser ASCII, UTF8 o cualquier otra cosa, para el caso. Debido a que la mayoría de los sistemas operativos entienden ASCII de forma predeterminada, y el código fuente se escribe principalmente con codificación ASCII, por lo que los datos que encontrará en un simple (char*) muy a menudo también serán ASCII. No obstante, no hay garantía de que lo que obtenga de un (char*) sea UTF8 o incluso KOI8.

  • En realidad, la mayoría de los sistemas operativos modernos utilizan una amplia cadena de caracteres en todas las interfaces internas (Win/Linux/Mac). Entonces no es ASCII lo que usan.

    – Martín York

    22 de octubre de 2010 a las 11:06

  • No dije que usan ASCII por defecto en sus interfaces, sino que entienden ASCII 🙂

    – freskoma

    22 de octubre de 2010 a las 11:10

  • “realmente no tiene ninguna codificación” El texto almacenado digitalmente siempre tiene alguna codificación.

    – Praxeolítico

    29 de noviembre de 2017 a las 6:00

  • @MartinYork Linux absolutamente no usa caracteres anchos internamente. Las interfaces POSIX están orientadas a bytes y son independientes de la codificación. MacOS también es POSIX con herencia BSD, espero que también use la codificación de bytes internamente.

    – Yakov Galka

    28 de octubre de 2021 a las 1:27

La norma no especifica esto. Normalmente con ASCII.

  • En Objective-C, puedo crear cadenas C usando el dicho char *cStr = [objcStr UTF8String]e imprimir como printf(“%s”, cStr). ¿Funciona porque ASCII es un subconjunto de UTF8?

    – Plumenador

    22 de octubre de 2010 a las 10:54

  • Sí, ASCII es un subconjunto de UTF8.

    – freskoma

    22 de octubre de 2010 a las 10:58

  • @Plumenator Funciona porque UTF-8 fue diseñado para ser lo más transparente posible para el código que ya maneja ASCII, y porque su terminal de salida es compatible con UTF-8

    – nos

    22 de octubre de 2010 a las 10:59

  • +1 @nos, pero para completar algunos detalles, funciona porque UTF-8 garantiza que el byte cero no se produce en ninguna codificación de caracteres multibyte, por lo que printf nunca entregará inadvertidamente solo una parte de una cadena codificada en UTF-8 al terminal.

    – Marcelo Cantos

    22 de octubre de 2010 a las 11:15


Como ya se indicó, C tiene algunas restricciones de lo que se permite para las codificaciones de caracteres de fuente y ejecución, pero es relativamente permisivo. Entonces, en particular, no es necesariamente ASCII y, en la mayoría de los casos, hoy en día al menos es una extensión de eso.

Su entorno de ejecución está destinado a realizar una traducción eventual entre el conjunto de caracteres fuente y de ejecución. Por lo general, no debe preocuparse por la codificación y, por el contrario, intente codificar independientemente de ella. Por eso hay secuencias de escape especiales para caracteres especiales como '\n'o '\t' y codificaciones de caracteres universales como '\u0386'. Por lo general, no debería tener que buscar las codificaciones para el conjunto de caracteres de ejecución usted mismo.

avatar de usuario
marcelo cantos

No están realmente “codificados” como tales, simplemente se almacenan tal cual. La cadena “hola” representa una matriz con los valores de char 'h', 'e', 'l', 'l', 'o' y '\0', en ese orden. El estándar C tiene un juego de caracteres básico que incluye estos caracteres, pero no especifica una codificación en bytes. Podría ser EBCDIC, por lo que sabe.

  • Nota: ‘\0’ es literalmente el número octal 0 con un tipo de carácter. Entonces, sí, el carácter final siempre es literalmente un 0.

    – Martín York

    22 de octubre de 2010 a las 11:02

  • @Martin: gracias por señalarlo. Siempre olvido si las reglas extrañas sobre los punteros nulos también se aplican a los caracteres nulos.

    – Marcelo Cantos

    22 de octubre de 2010 a las 11:10


  • @Martin: técnicamente, el tipo de carácter literal es int (al menos está en C)…

    –Oliver Charlesworth

    22 de octubre de 2010 a las 11:15

  • @Marcelo Estoy hablando de todos los personajes.

    – Plumenador

    22 de octubre de 2010 a las 11:23

  • @Plumenator: modifiqué mi respuesta en consecuencia.

    – Marcelo Cantos

    22 de octubre de 2010 a las 11:40

  • Nota: ‘\0’ es literalmente el número octal 0 con un tipo de carácter. Entonces, sí, el carácter final siempre es literalmente un 0.

    – Martín York

    22 de octubre de 2010 a las 11:02

  • @Martin: gracias por señalarlo. Siempre olvido si las reglas extrañas sobre los punteros nulos también se aplican a los caracteres nulos.

    – Marcelo Cantos

    22 de octubre de 2010 a las 11:10


  • @Martin: técnicamente, el tipo de carácter literal es int (al menos está en C)…

    –Oliver Charlesworth

    22 de octubre de 2010 a las 11:15

  • @Marcelo Estoy hablando de todos los personajes.

    – Plumenador

    22 de octubre de 2010 a las 11:23

  • @Plumenator: modifiqué mi respuesta en consecuencia.

    – Marcelo Cantos

    22 de octubre de 2010 a las 11:40

¿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