2012-03-18 18 views
10

desarrolladores de software populares y las empresas (Joel Spolsky, Fog Creek software) tienden a utilizar wchar_t para el almacenamiento de caracteres Unicode al escribir código C o C++. ¿Cuándo y cómo debe uno usar char y wchar_t con respecto a las buenas prácticas de codificación?Uso correcto de almacenamiento de cadenas en C y C++

Estoy particularmente interesado en POSIX conformidad al escribir software que aprovecha Unicode.

Al utilizar wchar_t, puede buscar caracteres en un array de caracteres anchos en función de cada carácter o por-array de elementos:

/* C code fragment */ 
const wchar_t *overlord = L"ov€rlord"; 
if (overlord[2] == L'€') 
    wprintf(L"Character comparison on a per-character basis.\n"); 

¿Cómo puede comparar bytes Unicode (o caracteres) cuando se usa char?

Hasta ahora mi forma preferida de la comparación de secuencias y caracteres de tipo Char en C a menudo se parece a esto:

/* C code fragment */ 
const char *mail[] = { "ov€[email protected]", "ov€[email protected]" }; 
if (mail[0][2] == mail[1][2] && mail[0][3] == mail[1][3] && mail[0][3] == mail[1][3]) 
    printf("%s\n%zu", *mail, strlen(*mail)); 

exploraciones de este método para el byte equivalente a un carácter Unicode. El símbolo del Euro Unicode ocupa 3 bytes. Por lo tanto, es necesario comparar tres bytes de matriz char para saber si los caracteres Unicode coinciden. A menudo necesita saber el tamaño del carácter o cadena que desea comparar y los bits que produce para que la solución funcione. Esto no parece una buena forma de manejar Unicode en absoluto. ¿Existe una mejor manera de comparar cadenas y elementos de caracteres del tipo char?

Además, al usar wchar_t, ¿cómo se puede escanear el contenido del archivo en una matriz? La función fread no parece producir resultados válidos.

+9

Unicode en C++: no use 'wchar_t', use una biblioteca Unicode adecuada. –

+3

'tienden a usar wchar_t para codificación de caracteres Unicode'. No; lo usan para el carácter _storage_ de Unicode, y hay una gran diferencia. –

+0

posible duplicado de [std :: wstring VS std :: string] (http://stackoverflow.com/questions/402283/stdwstring-vs-stdstring) –

Respuesta

10

Si sabe que se trata de unicode, ni char ni wchar_t son apropiados ya que sus tamaños son compilados/plataforma definida. Por ejemplo, wchar_t tiene 2 bytes en Windows (MSVC), pero 4 bytes en Linux (GCC). Los estándares C11 y C++ 11 han sido un poco más rigurosos y definen dos nuevos tipos de caracteres (char16_t y char32_t) con prefijos literales asociados para crear cadenas UTF- {8, 16, 32}.

Si necesita almacenar y manipular caracteres Unicode, debe usar una biblioteca que esté diseñada para el trabajo, ya que ni los estándares de lenguaje anteriores a C11 ni los anteriores a C++ 11 se han escrito teniendo en cuenta unicode. Hay un few to choose from, pero ICU es bastante popular (y es compatible con C, C++ y Java).

+3

Incluso C++ 11 es bastante ligero en las cosas Unicode. Más allá de exigir algunos tipos y conversiones estándar entre utf8/16/32, no encontrarás nada como intercalación, comparación, normalización, etc. –

+0

Solo como una adición, creo que C11 aquí intenta estar en sincronización con C++ 1 y presenta los mismos nuevos tipos 'char ?? _ t'. –

+0

Sí, C11 está sincronizado con C++ 11 para estos tipos/literales. –

0

Estoy particularmente interesado en POSIX cumplimiento al escribir el software que aprovecha la Unicode.

En este caso, es probable que desee utilizar UTF-8 (con char) como su tipo de cadena Unicode preferido.POSIX no tiene muchas funciones para trabajar con wchar_t — que es principalmente algo de Windows.

Este método explora el equivalente en bytes de un carácter unicode. El símbolo de Euro Unicode toma hasta 3 bytes. Por lo tanto, es necesario comparar tres bytes de matriz char para saber si los caracteres Unicode coinciden. A menudo, necesita conocer el tamaño del carácter o cadena que desea comparar y los bits que produce para que la solución funcione.

No, no es así. Simplemente compara los bytes. Si los bytes coinciden, las cadenas coinciden. strcmp funciona igual de bien con UTF-8 que con cualquier otra codificación.

A menos que desee algo así como una comparación insensible a mayúsculas y minúsculas o insensible a los acentos, en cuyo caso necesitará una biblioteca Unicode adecuada.

0

Nunca debe comparar los bytes, o incluso los puntos de código, para decidir si las cadenas son iguales. Eso se debe a que muchas cadenas pueden ser idénticas desde la perspectiva del usuario sin ser idénticas desde la perspectiva del punto de código.