Disponible la versión 6 de OrganiZATOR
Descubre un nuevo concepto en el manejo de la información.
La mejor ayuda para sobrevivir en la moderna jungla de datos la tienes aquí.

Curso C++

[Home]  [Inicio]  [Índice]


2.2.1a Los tipos carácter

§1 Presentación:

En este capítulo abordamos la importante cuestión de como son representados internamente los caracteres alfabéticos y numéricos (cifras), en los ordenadores en general y en el lenguaje C++ en particular. Describiremos los sistemas de codificación utilizados más frecuentemente, junto con una pequeña introducción a su historia (informática) y evolución, comenzando por el sistema ASCII por ser el más conocido.

§2 Juegos de caracteres

Recuerde que cuando un texto informático utiliza las expresiones juego de caracteres ("Character set") o codificación de caracteres ("Character encoding"), se refiere siempre a una convención (norma) para relacionar una secuencia de octetos con una secuencia de glifos (marcas o dibujos en un papel o en una pantalla) denominados genéricamente caracteres, que corresponden a letras, símbolos, cifras o ideogramas de un sistema de escritura. En el interior de la máquina, esta correspondencia entre glifos y octetos, se materializan en una tabla denominada página de códigos . Recuerde también que un determinado juego de caracteres se refiere generalmente a un idioma (aunque no siempre), y no tiene porqué contener todos los caracteres y signos del idioma.

Es interesante observar que desde el punto de vista de la codificación de caracteres, la correspondencia entre octetos y glifos es muy genérica, en el sentido en que por ejemplo, un octeto determinado puede corresponder con la letra latina "A" mayúscula, pero no contiene ninguna indicación o detalle sobre su representación, como tipo de letra a utilizar, tamaño, color, o cualquier otra característica tipográfica que pudiera utilizarse en la representación de dicho carácter. Esos detalles no corresponden a la capa de software encargada de la codificación, sino a la que gobierna la interfaz hombre-máquina.

Actualmente las diversas culturas vivas del mundo utilizan unos 30 juegos de caracteres distintos, algunos de los cuales sirven a más de una lengua. Como el romano, utilizado en Europa occidental y otros países del mundo, o el cirílico, utilizado en países eslavos ( Juegos de caracteres).  Básicamente existen dos tipos: alfabéticos e ideográficos.  Los primeros corresponden a lenguas en las que existe el concepto de palabras formadas por caracteres del alfabeto. En este caso, los caracteres se denominan letras, símbolos de puntuación o cifras (según representan). Los segundos corresponden a lenguas en las que una idea u objeto son descritos mediante un solo glifo, que en este caso se denomina ideograma.

El tipo char nació en el primitivo C de K&R, y fue diseñado para contener un tipo especial de dato: los cracteres alfanuméricos del idioma inglés-americano. Teniendo en mente los caracteres que se utilizaban en la informática de la época, se consideró suficiente asignarle un espacio de almacenamiento de 1 byte. Esta es precisamente la definición ANSI de byte en C y C++: la memoria requerida para almacenar un carácter. En consecuencia, en estos idiomas siempre se cumple que sizeof(char) == 1 ( 4.9.13 ).

§3 El código ASCII

Como su propio nombre indica, ASCII (American Standard Code for Information Interchange), tiene origen americano, en el instituto ANSI [1].  El ASCII es simplemente una convención para codificar un conjunto de 128 caracteres (letras, números y símbolos), numerados del 0 a 127. Este número se debe a que emplea sólo 7 bits (27 == 128), algo que parecía suficiente en la época en que se propuso el estándar. Mucha gente cree que el código ASCII tiene 256 caracteres (numerados del 0 al 255), que es la capacidad de los 8 bits de un Byte, pero lo cierto es el denominado "ASCII puro", también conocido como US-ASCII (técnicamente es el ANSI X3.4-1968), se compone de sólo 7 bits y 128 caracteres (rango 00h-7fh si lo expresamos en hexadecimal). El primero es el carácter nulo, y tiene el número 0; el último es el 127.

En los 128 caracteres del código ASCII original se encuentran las letras del alfabeto inglés (mayúsculas y minúsculas), los números, y algunos signos comunes (espacio en blanco, paréntesis, corchetes, suma y resta, dólar, porcentaje, etc.) además de otros como retorno de carro, tabulador, campana, etc. Estos últimos, que eran necesarios para controlar el funcionamiento de los antiguos teletipos, ocupan las 32 primeras posiciones y la última, y se denominan precisamente por eso caracteres de control o no imprimibles.  Puesto que no representan ninguna letra ni signo de puntuación, se designan mediante nemónicos (NULL, NAK, CR, NL, Etc. [5]).  Ver nota a continuación .

Juego de caracteres US-ASCII    

  0 1 2 3 4 5 6 7 8 9 A B C D E F
0 NUL SOH STX ETX EOT ENO ACK BEL BS TAB LF VT FF CR SO SI
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
2   ! " # $ % & ' ( ) * + , - . /
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
4 @ A B C D E F G H I J K L M N O
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
5 P Q R S T U V W X Y Z [ \ ] ^ _
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
6 ` a b c d e f g h i j k l m n o
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
7 p q r s t u v w x y z { | } ~ DEL
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127


Leyenda: el valor Hexadecimal se encuentra entrando en la fila y columna. Por ejemplo, el carácter "A" está en fila 4 columna 1, luego su valor hexadecimal es 41 = 41h ( 2.2.4b).  El valor decimal se ha incluido debajo de cada carácter (en color azul), para la "A" es 65. Los caracteres no representables se han indicado por sus nemónicos (en color verde). Al carácter "espacio" le corresponde el decimal 32 (20h).

Nota:  la tabla adjunta incluye los nombres completos y valor decimal de algunos acrónimos muy utilizados en textos informáticos. La columna "Gen." señala la forma en que puede generarse el carácter de control desde el teclado.

Acrónimo Gen.

Nombre completo

ASCII

Comentario

NUL Ctrl-@ Null 0 Carácter nulo; un carácter como los demás, que puede ser definido mediante '\0' No confundir con la constante NULL definida en muchos compiladores y librerías como el puntero nulo ( 4.2.1).  Recuerde que NUL y NULL son tipos distintos. A su vez este último no tiene ninguna relación con el NULL utilizado en muchas bases de datos relacionales, donde se refiera a ausencia de valor o valor no definido.
SOH Ctrl-A Start of Header 1  
STX Ctrl-B Start of Text 2  
ETX Ctrl-C End of Text 3  
EOT Ctrl-D End of Transmission 4  
ENQ Ctrl-E Enquiry 5  
ACK Ctrl-F Acknowledge 6  
BEL Ctrl-G Bell 7 Señal acústica que sonaba en los teletipos para recabar atención del operador.
BS Ctrl-H Back Space 8 Retroceso/retorno de carro
HT Ctrl-I Horizontal Tab 9 Tabulación horizontal
LF/NL Ctrl-J Line Feed/New Line 10 Salto de línea / Nueva línea (espacio vertical).  Representado por el dígrafo \n en la mayoría de lenguajes y textos informáticos.
VT Ctrl-K Vertical Tab 11 Tabulación vertical
FF Ctrl-L Form Feed 12 Salto de página
CR Ctrl-M Carriage Return 13 Retorno de carro de impresión. También suele ser representado por el dígrafo \r
SO Ctrl-N Shift Out 14  
SI Ctrl-O Shift In 15  
DLE Ctrl-P Data Link Escape 16  
DC1 Ctrl-Q Device Control 1 17 También conocido como XON [6]
DC2 Ctrl-R Device Control 2 18  
DC3 Ctrl-S Device Control 3 19 También conocido como XOFF [6]
DC4 Ctrl-T Device Control 4 20  
NAK Ctrl-U Negative Acknowledge 21  
SYN Ctrl-V Synchronous Idle 22  
ETB Ctrl-W End Transmission Block 23  
CAN Ctrl-X Cancel 24  
EM Ctrl-Y End of Medium 25  
SUB Ctrl-Z Substitute 26  
ESC Ctrl-[ Escape 27  
FS Ctrl-\ File Separator 28  
GS Ctrl-] Group Separator 29  
RS Ctrl-Ctrl Record Separator 30  
US Ctrl-_ Unit Separator 31  
SP   Space 32 Espacio horizontal
DEL   Delete / rubout 127  
CHAR   Character 0 - 127 Cualquier carácter US-ASCII
CTL     0-31+ 127 Cualquier carácter de control
UALPHA     65 - 90 Cualquier mayúscula "A"..."Z"
  Ctrl Control 94 Representado por el símbolo ^
LOALPHA     97 -122 Cualquier minúscula "a"..."z"
ALPHA       Cualquier letra, mayúscula o minúscula
DIGIT     48 - 57 Cualquie dígito "0"..."9"
§3.1 El ASCII extendido

Con la internacionalización de los ordenadores, se cayó en la cuenta que los 128 caracteres del US-ASCII no eran suficientes para trabajar con los signos de otros idiomas (tildes; signos especiales como las interrogaciones o exclamaciones de apertura; letras como la eñe, la cedilla y otras), de modo que los fabricantes comenzaron a usar un conjunto de caracteres ASCII ampliado de 8 bits (256 caracteres), que además coincidía con el tamaño de palabra de los procesadores de la época. Las 128 posiciones primeras seguían conteniendo el US-ASCII, pero en los 128 caracteres adicionales, que constituyen lo que se denomina ASCII extendido, añadieron todas las letras y signos especiales de uso común en lenguas de Europa occidental, como el español, francés o alemán.

Por desgracia, en aquel momento no se siguieron estándares únicos, ni hubo una decisión internacional al respecto. Cada fabricante de ordenadores y software usó su propio código seudo-ASCII en variaciones nacionales o de sistema operativo, construyendo sus propias páginas de códigos (§5 ) sin pensar en los problemas que esto acarrearía a la informática del futuro, con lo que se originó una pequeña "Babel" de sistemas de codificación de caracteres que perdura hasta hoy.

Actualmente, el juego de caracteres ASCII extendido de los PC es distinto en MS-DOS y MS-Windows, distinto a su vez del "ASCII Macintosh" y del ASCII Unix; del de algunos sistemas IBM, y desde luego de otros muchos sistemas operativos antiguos y modernos [2]. Algunas de estas versiones de ASCII extendido se han estandarizado. Ver a continuación el Estándar ISO 8859 .

Por su parte, en la época del desarrollo del C original (la primera edición del libro de K&R es de 1978), ya se utilizaba el ASCII extendido, y por supuesto, las 256 posibilidades de un byte eran suficientes para albergar los caracteres definidos en el Estándar, por lo que al tipo char se le asignó 1 octeto.

§3.2 Evolución del ASCII

De entre todos los sistemas ASCII de 8 bits (SBCS "Single Byte Character Sets"), los que han alcanzado mayor fortuna han sido dos: El que se incorporó por defecto en los PCs de IBM en la década de los 80, y posteriormente, el de los sistemas Windows 9x de MS.

El juego de caracteres del PC, incorporó símbolos especiales para representar visualmente (en la pantalla) los caracteres de control que hasta entonces no tenían representación gráfica. El juego de caracteres extendido se muestra en la tabla adjunta.

§4.2a Juego de caracteres extendidos ASCII-PC


En lo
que respecta a Microsoft, el gigante de la informática incorporó en sus sistemas Windows 9x un juego de caracteres bastante adaptado a la mayoría de los alfabetos occidentales. Posteriormente implementó en sus sistemas NT y sucesores, un sistema denominado Unicode que utiliza 16 bits para representar los caracteres; sus 65.537 posibilidades permiten representar los de todas las lenguas del mundo ( 2.2.1a2).

Nota: en las páginas siguientes se detallan las características de los sistemas de codificación multibyte, que representan el último paso evolutivo de los sistemas SBCS.


§3.2b
El cojunto de caracteres ASCII extendido tal como se ven en un sistema Windows 9x (los caracteres marcados _, no tienen representación gráfica visible en MS Windows 98 con I. Explorer 5.50).

§3.2c Juego de caracteres ASCII extendido tal como son generados en su computadora

  0 1 2 3 4 5 6 7 8 9 A B C D E F
8 €  ‚ ƒ „ … † ‡ ˆ ‰ Š ‹ Œ  Ž 
9  ‘ ’ “ ” • – — ˜ ™ š › œ  ž Ÿ
A   ¡ ¢ £ ¤ ¥ ¦ § ¨ © ª « ¬   ® ¯
B ° ± ² ³ ´ µ · ¸ ¹ º » ¼ ½ ¾ ¿
C À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï
D Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß
E à á â ã ä å æ ç è é ê ë ì í î ï
F ð ñ ò ó ô õ ö ÷ ø ù ú û ü ý þ ÿ


§3.3  A continuación se muestra una calculadora interactiva [4] para representar los caracteres ASCII y sus valores numéricos correspondientes en los diversos sistemas: Decimal, Hexadecimal y Octal (Válido para los navegadores Netscape 3+ y MS IE 4+):

Dec:
Hex:
Octal:
ASCII:

Escribir en la casilla correspondiente y pulsar TAB
§4 Página de códigos

Los juegos de caracteres, ya sean ASCII, Unicode o de cualquier tipo, se materializan dentro de la máquina en unas tablas denominadas páginas de códigos, que establecen la relación entre cada glifo y su valor numérico [8]. Las páginas de códigos pueden ser cualquiera, incluso construidas por el usuario, pero las utilizadas más frecuentemente están estandarizadas. Existen dos tipos:

  • ACP ("ANSI Code Pages") Las que han sido estandarizadas por el Instituto de Estándares Americano. Por ejemplo: la página de códigos ANSI 1252 corresponde al Inglés-Americano y a la mayoría de lenguas de Europa occidental.

  • OCP ("OEM Code Pages") Son propuestas por fabricantes u organizaciones no oficiales (OEM significa "Original Equipment Manufacturer"). Por ejemplo, la OEM 932 corresponde al juego Kanji de caracteres Japoneses ( 2.2.1a0), mientras que el OEM 949 representa un juego de caracteres Coreano.

Generalmente las páginas de código son mantenidas por el Sistema Operativo, y existen en dos versiones: para caracteres normales y para caracteres anchos. Los programas C/C++ las utilizan de dos modos: forma controlada explícitamente por el programador en runtime ( 5.2), o controlada por el propio compilador que selecciona unas páginas por defecto que son cargadas desde el Sistema anfitrión como parte de las rutinas de inicio.

El MS-DOS, quizás el primer Sistema Operativo que llegó a ser verdaderamente universal, utilizó distintas páginas de código con una nomenclatura propia para extender este Sistema a entornos distintos del Inglés-Americano. Por ejemplo:

437 Inglés-USA (del PC original IBM)

737 Griego

862 Hebreo
863 Franco-Canadiense
850 Multi-Lingual (Latín-1)
865 Nórdico
860 Portugués
852 Eslavo (Latín-2)

A su vez, el Estándar ISO 8859 establece 15 páginas de código, de las que se han reservado diez para las lenguas que utilizan un juego de caracteres de raíz latina [7]:

ISO 8859-1 (Latin-1) Europa occidental
ISO 8859-2 (Latin-2) Europa oriental (países eslavos)
ISO 8859-3 (Latin-3) Europa suroriental
ISO 8859-4 (Latin-4) Europa septentrional

ISO 8859-5 Cirílico
ISO 8859-6 Árabe
ISO 8859-7 Griego
ISO 8859-8 Hebreo

ISO 8859-9 (Latin-5) Europa oriental + Turquía

ISO 8859-10 (Latin-6)

ISO 8859-11 Latin/Thai

ISO 8859-13 (Latin-7)

ISO 8859-14 (Latin-8) Celta

ISO 8859-15 (Latin-9)

ISO 8859-16 (Latin-10) 

Observe que un lenguaje natural utiliza siempre la misma página de códigos (la que contiene todos sus caracteres y signos de puntuación), pero una página de códigos no tiene porqué estar relacionada únicamente con un lenguaje. Por ejemplo, la página ANSI 1252 puede ser utilizada por los lenguajes Inglés, Español y Francés porque contiene todos los caracteres utilizados en estas lenguas.

Nota: Windows XP y Windows 2000 disponen de la utilidad charmap, que permite ver los caracteres disponibles en una fuente seleccionada, así como mostrar los juegos de caracteres: Windows, DOS y Unicode.  Puede copiar caracteres individuales o un grupo de caracteres al Portapapeles y pegarlos en cualquier programa que pueda mostrarlos. También permite buscar caracteres por el nombre de carácter Unicode o un subgrupo Unicode (por ejemplo, flechas u operadores matemáticos).


Como se ha señalado anteriormente (§4.1 ), las páginas de código de caracteres normales tienen 256 posiciones, aunque la mayoría comparte 128 posiciones con el juego de caracteres ASCII (el rango 0x00-0x7F). En cambio, las páginas de caracteres anchos son muy grandes (64 K entradas), aunque no suelen cargarse completas, solo las primeras 256 posiciones y ciertas zonas correspondientes a los rangos que utilizará el programa [3].

Como veremos al tratar de la internacionalización de los programas ( 5.2), muchas funciones de la Librería Estándar C++ para manipulación de caracteres normales y caracteres anchos, adaptan su comportamiento a la página de códigos correspondiente que haya sido cargada.


Recordar que la Librería Estándar C++ ( 5) dispone de funciones especiales para determinar ciertas características de cualquier carácter. Por ejemplo, si es imprimible (representable gráficamente); si es un dígito o carácter alfabético; si es ASCII, etc. Ver: isalpha(); isascii(); iscntrl();  isdigit(); isgraph(); islower(); etc.

  Inicio.


[1] ANSI  (American National Standards Institute). Este instituto, fundado en 1918, es una organización compuesta por unos 1300 miembros, incluyendo las compañías de informática más importantes. Se encarga de redactar los estándares para USA.   http://web.ansi.org.  A su vez es miembro de la Organización Internacional de Estandarización ISO (International Standards Organization). Fundada en 1946, agrupa 89 países miembro, y es responsable de los estándares a mundiales en muchas áreas, incluyendo electrónica e informática.   http://www.iso.ch/

[2] El libro de Mackenzie "Coded Character Sets" es "La Biblia" al respecto de la historia de este juego de caracteres.

[3] No tiene sentido cargar el conjunto Japones de caracteres Kanji, que tiene decenas de miles de entradas, si no vamos a utilizar este idioma en nuestro programa. A título de ejemplo, señalemos que el documento Unicode que describe el juego de caracteres Latino básico ocupa 126 KB. mientras que el documento análogo para el juego de ideogramas Kanji ocupa 5.316 MB.

[4] Reproducido aquí por cortesía de Juan Soulie <juan@soulie.com>

[5] Cuando se trata de escritura normal se utilizan estos nemónicos. Por ejemplo, es corriente ver escrito algo como "Salir con ESC" para designar la tecla que produce este carácter. En cambio, cuando se trata de representarlos en el texto del código fuente, se utilizan las denominadas secuencias de escape ( 3.2.3e)

[6]  Estos caracteres tienen un significado especial en el caso de transmisiones serie cuyo control de flujo se realiza por software: la recepción de un carácter XOFF en el transmisor, es una petición del receptor para que suspenda momentáneamente el flujo transmitido, mientras que XON tiene el significado contrario.

[7]  Las páginas de códigos "Latin" del estándar ISO no guardan ninguna relación con las páginas de código del MS-DOS.

[8]  En el texto hemos empleado la palabra "glifo" (figura o signo). Por ejemplo, la figura que en nuestro idioma representa a la letra A mayúscula, para referirnos a la imagen que representa a las letras, cifras o signos de puntuación, pero observe que no nos referimos a ninguna forma concreta. Piense por ejemplo en que la representación en mayúscula de la primera letra del alfabeto ("A") puede tener múltiples formas concretas. A, A, A, A, A, etc.  Las posibilidades concretas de representación dependen entre otros factores, del juego de fuentes ("fonts") disponibles en el ordenador.