2009-10-23 11 views
6

¿Cómo convierto una cadena wchar_t de mayúsculas a minúsculas en C++?Conversión de cadenas de caracteres anchas a minúsculas en C++

La cadena contiene una mezcla de caracteres japoneses, chinos, alemanes y griegos.

Pensé en usar towlower ...

http://msdn.microsoft.com/en-us/library/8h19t214%28VS.80%29.aspx

.. pero la documentación dice que:

El caso conversión de towlower es específico de la localidad. Solo los caracteres relevantes para la configuración regional actual se cambian en el caso.

Editar: Tal vez debería describir lo que estoy haciendo. Recibo una consulta de búsqueda Unicode de un usuario. Originalmente está en codificación UTF-8, pero lo estoy convirtiendo en un widechar (puedo estar equivocado en la redacción). Mi depurador (VS2008) muestra correctamente los caracteres japoneses, alemanes, etc. en el "reloj rápido variable". Necesito revisar otro conjunto de datos en Unicode y encontrar coincidencias de la cadena de búsqueda. Si bien este no es un problema para mí cuando la búsqueda es sensible a las mayúsculas y minúsculas, es más problemático hacerlo insensible a mayúsculas y minúsculas. Mi (quizás ingenuo) enfoque para resolver el problema sería convertir todos los datos de entrada y salida a minúsculas y luego compararlas.

+3

otro enfoque sería utilizar algoritmos de comparación que ignoran el caso. Y el caso no es tu único problema. Sin normalizar la cadena, los diacríticos, por ejemplo, pueden considerarse parte de uno ('é',' Õ'), o varios caracteres individuales (''e',' ~ O'). La correcta normalización (NFC/NFD/NFKC/NFKD) antes de la comparación es vital en su situación. – Abel

+0

Abel, publícalo como respuesta adecuada para que pueda ser votado como debería ser. Es casi la única respuesta correcta en esta situación ... –

Respuesta

9

Si su cadena contiene todos esos caracteres, el conjunto de códigos debe estar basado en Unicode. Si se implementa correctamente, Unicode (Capítulo 4 'Character Properties') define las propiedades de los caracteres, incluso si el carácter es mayúscula y el mapeo en minúscula, y así sucesivamente.

Dado que el preámbulo, la función towlower() de <wctype.h> es la herramienta correcta para usar. Si no cumple con su función, tiene un problema de calidad de funcionamiento (QoI) para analizar con su proveedor. Si encuentra que el proveedor no responde, mire las bibliotecas alternativas. En este caso, puede considerar ICU (Componentes internacionales para Unicode).

+2

Las asignaciones de casos Unicode, tal como se especifica en el documento al que se ha vinculado, aún dependen parcialmente de la configuración regional. Cita: "SpecialCasing.txt: contiene asignaciones de casos adicionales que se asignan a más de un carácter, como" ß "a" SS ". También contiene asignaciones dependientes del contexto, con indicadores para distinguirlas de las asignaciones normales, así como _some mapeos dependientes de la ubicación_. ". Entonces 'tolower' no puede evitar ser específico de la configuración regional. –

+0

@Pavel Este proceso se llama "normalización de cadenas Unicode", lo que asegura que 'ß' y' ss' sean tratados igual (dependiendo de la forma de normalización elegida) y Unicode contiene algoritmos de lenguaje neutral para eso, sin ignorar el deseo para el tratamiento específico de la localidad o la aplicación. – Abel

+2

@Abel: la normalización no es una solución completa. Por ejemplo, en algunos idiomas latinos los signos diacríticos desaparecen en letras mayúsculas, en otros idiomas no. No hay forma de saber a menos que sepas en qué idioma está escrito el texto. Luego, por supuesto, está el infame problema "i" sin puntos turco: quieres 'İ' para minúsculas para' i' y 'I' para reducirlo a' ı' para turco, pero quiere 'I' a minúscula para 'i' para cualquier otro idioma de alfabeto latino. –

3

Tiene un desagradable problema en la mano. Un local japonés no ayudará a convertir alemán y viceversa. Hay idiomas que no tienen el concepto de captalización tampoco (toupper y los amigos serían un no-operativo aquí, supongo). Entonces, ¿puedes dividir tu cadena en trozos individuales de palabras del mismo idioma? Si puede, puede convertir las piezas y atarlas.

+0

El japonés y otros idiomas ideográficos del este de Asia son ejemplos de idiomas, principalmente sin mayúsculas. –

+5

No solo eso, sino que los idiomas individuales pueden tener _diferentes_ opiniones sobre cómo una letra en particular debe ser mayúscula o minúscula. Simplemente no hay un solo algoritmo para hacerlo correctamente en cualquier cadena Unicode al azar sin conocer el idioma. –

+1

Aunque estoy de acuerdo con esa evaluación, Unicode incluye propiedades en mayúsculas/minúsculas independientes de la configuración regional, su uso se describe en * 3.13 "Opción de casos predeterminados" *, que * se utilizarán en ausencia de adaptación para idiomas particulares *, por lo que el estándar dice. – Abel

1

This SO answer muestra cómo trabajar con facetas para trabajar con varias configuraciones regionales. Si esto está en Windows, puede considerar el uso de las funciones API de win32, si puede trabajar con C++ .NET (C++ administrado), puede usar las funciones char.ToLower y string.ToLower, que son compatibles con Unicode.

0

Eche un vistazo a _wcslwr_l en <wchar.h> (MSDN).

Debería poder ejecutar la función en la entrada para cada una de las configuraciones regionales.

+0

"Debería poder ejecutar la función en la entrada para cada una de las configuraciones regionales". - ¿Qué pasa si dos configuraciones regionales en el conjunto asignan el mismo personaje de manera diferente? –

+0

Como se menciona en otros comentarios, debe conocer el idioma de cada parte de la cadena para evitar esos casos. Realmente no hay forma de evitar eso. Simplemente estoy sugiriendo una función diferente que usar para administrar más fácilmente el problema con la ejecución de la operación en la configuración regional actual. –

Cuestiones relacionadas