[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