2012-05-13 37 views
5

tengo este código:comportamiento incorrecto de tamaño() y al() en la clase string

string test("żaba"); 

cout << "Word: " << test << endl; 
cout << "Length: " << test.size() << endl; 
cout << "Letter: " << test.at(0) << endl; 

La salida es extraño:

Word: żaba 
Length: 5 
Letter: � 

Como se puede ver, la longitud debe ser 4 y letra: "ż".

¿Cómo puedo corregir este código para que funcione correctamente?

+3

Estos son los caracteres Unicode, por lo tanto, probablemente debería ser el uso de las amplias versiones de estas funciones/tipos de datos: 'std :: wstring' y' std: : wcout'. –

+0

Lectura esencial: http://www.joelonsoftware.com/articles/Unicode.html –

+0

eche un vistazo a esto: http://en.cppreference.com/w/cpp/string/multibyte –

Respuesta

5

std::string en Windows se usa generalmente para almacenar cadenas UTF8 (siendo la codificación predeterminada en la mayoría de los sistemas operativos de este lado de 2010), pero es un contenedor "tonto" que en el sentido de que no sabe o le importa cualquier cosa sobre los bytes que está almacenando. Funcionará para leer, almacenar y escribir; pero no para la manipulación de cuerdas.

Debe utilizar el excelente y bien mantenido IBM ICU: Componentes internacionales para Unicode. Es una biblioteca C/C++ para * nix o Windows a la que se ha dedicado una tonelada de investigación para proporcionar una biblioteca de cadenas con reconocimiento de cultura, que incluye una comparación de cadenas insensible a las mayúsculas y minúsculas que es rápida y precisa.

Otro buen proyecto que es más fácil cambiar a para desarrolladores C++ es UTF8-CPP

+0

"std :: string on non-Windows is UTF8" - ¡No, en absoluto! 'std :: string' no se preocupa por las codificaciones de caracteres, solo administra matrices de caracteres de tipo' char'. –

+0

Sí, no en ese sentido. Voy a actualizar. –

+0

¡Elimine la referencia UTF8! Aunque 'std :: string' puede * mantener * estas cadenas, solo funcionará con codificaciones de un solo carácter. Ni siquiera el 'length()' es correcto. ¿De qué sirve utilizar 'std :: string' para almacenar UTF-8 codificado en varios bytes si no puede hacer nada con eso? También podría usar un 'std :: vector ' y luego. –

6

Su pregunta no menciona codificaciones así que voy a tomar una puñalada en la oscuridad y decir que esta es la razón.

Primera línea de acción: leer The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!).

Después de eso, debe quedar claro que algo así como una "cuerda desnuda" no existe; cada cadena está codificada de alguna manera. En su caso, se parece mucho a que está utilizando una cadena codificada en UTF-8 con signos diacríticos, en cuyo caso, sí, la longitud de la cadena se informa (correctamente) como 5 , y el primer punto de código podría no ser imprimible en su plataforma.


1) Tenga en cuenta que el recuento string::size bytes (= char s), personajes no lógicas o incluso puntos de código.

+0

+1 para el enlace, obviamente! –

Cuestiones relacionadas