2009-01-21 44 views
5

¿Hay un wchar_t portátil en C++? En Windows, sus 2 bytes. En todo lo demás es de 4 bytes. Me gustaría usar wstring en mi aplicación, pero esto causará problemas si decido hacia abajo para portarlo.Wchar_t portátil en C++

+0

¿Necesitaría compartir datos entre Windows y otras instalaciones del SO (por ejemplo, archivos, sockets)? De lo contrario, creo que no es necesario que se preocupe por este problema (siempre que use sizeof en lugar de 2 o 4). –

+0

Planeo usar una base de datos SQLite. –

+0

http://stackoverflow.com/questions/421530/is-endian-conversion-required-for-wchart-data#421603 –

Respuesta

4

Si está tratando con el uso interno del programa, no se preocupe; un wchar_t en la clase A es el mismo que en la clase B.

Si está planeando transferir datos entre las versiones de Windows y Linux/MacOSX, tiene más de qué preocuparse wchar_t, y debe aparecer con medios para manejar todos los detalles.

Puede definir un tipo que definirá como cuatro bytes en todas partes e implementar sus propias cadenas, etc. (ya que la mayoría del manejo de texto en C++ está modelado), pero no sé qué tan bien funcionaría para tus necesidades

Algo así como typedef int my_char; typedef std::basic_string<my_char> my_string;

+0

Necesitaría char_traits para eso, y puede 'especializar std :: char_traits (por reglas de espacio de nombres std). – MSalters

+0

Además, simplemente puede usar wchar_t/wstring internamente. Externamente, usa UTF-8 para eludir el desastre de endiannness. En I/O, convierta entre wchar_t y UTF-8 usando funciones de plantilla especializadas en sizeof (wchar_t). – MSalters

+0

-1 Usar my_char es mala idea. Puedes escribir una cadena para transmitir, no puedes hacer nada con ella – Artyom

3

¿Qué quiere decir con "portable wchar_t"? Hay un tipo de uint16_t que tiene 16bits de ancho en todas partes, que a menudo está disponible. Pero eso, por supuesto, no forma una cadena todavía. Una cadena debe conocer su codificación para dar sentido a funciones como length(), substring() y así sucesivamente (para que no corte caracteres en el medio de un punto de código cuando se utiliza utf8 o 16). Hay algunas clases de cadenas compatibles con Unicode que conozco que puedes usar. Todos pueden ser utilizados en programas comerciales de forma gratuita (el Qt one será compatible de forma gratuita con los programas comerciales en un par de meses, cuando se publique Qt 4.5).

ustring del proyecto gtkmm. Si programa con gtkmm o usa glibmm, esa debería ser la primera opción, usa utf-8 internamente. Qt también tiene una clase de cadena, llamada QString. Está codificado en utf-16. ICU es otro proyecto que crea clases de cadenas unicode portátiles, y tiene una clase UnicodeString que internamente parece estar codificada en utf-16, como Qt. Aunque no he usado ese.

+1

En realidad, length(), substring() y Co. no tienen ni idea de la codificación, simplemente miran el tamaño de la unidad de codificación y trabajan en eso. –

+0

@Mihai, seguro que ese es el caso de la función de std :: string. Pero esa es la razón por la que no se puede usar para utf8, etc. –

+0

@Johannes Schaub: pero la respuesta dice "Una cadena debe conocer su codificación para dar sentido a funciones como length(), subserie()" Así que no, no tiene que saber. Puede trabajar en términos de unidades de código sin conocer la codificación, todo lo que necesita es el tamaño de la unidad de código. –

1

El estándar C++ 0x propuesto tendrá char16_t y char32_t tipos. Hasta entonces, tendrás que recurrir al uso de números enteros para el tipo de carácter que no sea wchar_t.

#if defined(__STDC_ISO_10646__) 
    #define WCHAR_IS_UTF32 
#elif defined(_WIN32) || defined(_WIN64) 
    #define WCHAR_IS_UTF16 
#endif 

#if defined(__STDC_UTF_16__) 
    typedef _Char16_t CHAR16; 
#elif defined(WCHAR_IS_UTF16) 
    typedef wchar_t CHAR16; 
#else 
    typedef uint16_t CHAR16; 
#endif 

#if defined(__STDC_UTF_32__) 
    typedef _Char32_t CHAR32; 
#elif defined(WCHAR_IS_UTF32) 
    typedef wchar_t CHAR32; 
#else 
    typedef uint32_t CHAR32; 
#endif 

Según la norma, que necesitará para especializarse char_traits de los tipos enteros. Pero en Visual Studio 2005, he salido con std::basic_string<CHAR32> sin un manejo especial.

Planeo usar una base de datos SQLite.

Luego tendrá que usar UTF-16, no wchar_t.

La API SQLite también tiene una versión UTF-8. Es posible que desee utilizar eso en lugar de ocuparse de las diferencias wchar_t.

0

Mi sugerencia. Use UTF-8 y std :: string. Las cuerdas anchas no te aportarán demasiado valor añadido. Como de todos modos no se puede interpretar el carácter ancho como una letra como algunos caracteres encuadrados a partir de varios puntos de código Unicode.

Úselo en cualquier lugar UTF-8 y use una buena biblioteca para tratar con idiomas naturales. Como por ejemplo Boost.Locale.

Mala idea: definir algo así como typedef uint32_t mychar; es malo. Como no puede usar iostream con él, no puede crear, por ejemplo, un flujo de cadenas basado en este carácter, ya que no podría escribir en él.

Por ejemplo esto no funcionaría:

std::basic_ostringstream<unsigned> s; 
ss << 10; 

no se crearía una cadena.