[C con Clase] c y unicode

Steven Davidson srd4121 en njit.edu
Mie Sep 1 19:55:06 CEST 2010


Hola Adolfo,

On 9/1/2010 11:52 AM, Adolfo Cárdenas wrote:
> Gracias
> Me gustaría saber que hace la funcion TEXT

Se trata de una macro que acepta una cadena literal. Básicamente, 
convierte la cadena literal a una de tipo 'char' o a una de tipo 
'wchar_t', según si el símbolo 'UNICODE' está #definida o no. En la 
práctica, tenemos esto:

#ifdef UNICODE
   #define TEXT(s) L##s
#else
   #define TEXT(s) s
#endif

La verdad es que 'TEXT()' se #define como '__TEXT()', y ésta se #define 
de igual manera que acabo de escribir.

Por ejemplo,

TEXT( "HOLA" )

acaba siendo:

L"HOLA"

si #definimos UNICODE.

> y por que no se utiliza simplemente (WCHAR*) para la conversión

La única conversión es de tipo, porque prácticamente pasas de un puntero 
a 'CHAR' a un puntero a 'WCHAR'. La cuestión es que conviertes un 
puntero a otro. Por lo tanto, la información apuntada no varía. Esto 
significa que 'TextOut()', como cualquier otra función, interpreta la 
información apuntada de diferente manera.

Ten presente que 'CHAR' (o 'char') ocupa 1 byte, mientras que 'WCHAR' (o 
'wchar_t') ocupa 2 bytes. Por lo tanto, si leemos cada byte para 
representar un carácter, pero realmente es de 2 bytes (de Unicode), 
entonces estamos interpretando incorrectamente la información; de hecho 
acabaríamos procesando la mitad de la información.

Esto es análogo a hacer esto:

short int lista[4] = { 10, 20, 30, 40 };

Mostrar_Lista( (int *)lista, 2 );

teniendo en cuenta que esta función se define así:

void Mostrar_Lista( int *ptr, int n )
{
   do
     cout << *ptr++ << endl;
   while( --n );
}

El puntero 'lista' cambia de un puntero a 'short int' al mismo puntero 
pero a 'int'. Los elementos no cambian, pero la interpretación sí, 
porque ahora accedemos a cada elemento apuntado por 'ptr' como si se 
tratara de 'int' en lugar de 'short int'.

En el ejemplo anterior, aparecería lo siguiente en pantalla:

1310730
2621470

Esto es porque al acceder a un elemento según 'ptr', leemos 4 bytes, que 
en este caso son (en hexadecimal): 0x0014000A 0x28001E00. Originalmente, 
teníamos esta secuencia: 0x0A00 0x1400 0x1E00 0x2800, si 'short int' 
ocupa 2 bytes.

Por cierto, he representado esta información de la misma manera que lo 
hace Intel y otros procesadores compatibles. Por eso obtenemos (en decimal):
'lista': 10 20 30 y 40,
'ptr': 1310730 y 2621470

> ¿No estan los bytes ordenados de manera simple?

No estoy muy seguro a qué te refieres con una ordenación simple. Quizá 
te refieras a las cantidades de los bytes o posiblemente a la ordenación 
que hace Intel y otros procesadores de tipo "little-endian"; he 
explicado ambas posibilidades anteriormente.

> El problema es que yo leo bytes desde un archivo unicode
> y luego tengo que mostrar en el TextOut  parte de los bytes leidos.

Entonces guárdalos en un 'WCHAR', si sabes a ciencia cierta que se trata 
de Unicode. Por ejemplo,

WCHAR wszTexto[10240] = L"";

wifstream wifs( "datos.dat", ios::binary | ios::in );

wifs.read( wszTexto, 10240 );
...
TextOut( hdc, x,y, wszTexto, 10240-1 );  // Sin mostrar el carácter nulo

También podríamos usar 'TextOutW()' directamente.


Espero haber aclarado las dudas.

Steven





Más información sobre la lista de distribución Cconclase