Después de tanto luchar ya dimos con la solución de este atolladero que algunos lectores de nuestro espacio presentan. Si deseas compartir algún detalle no dejes de aportar tu conocimiento.
Solución:
No existe una forma estándar de realizar la conversión de mayúsculas y minúsculas Unicode en C ++. Hay formas que funcionan algunos Implementaciones de C ++, pero el estándar no las requiere.
Si desea una conversión de caso Unicode garantizada, deberá utilizar una biblioteca como ICU o Boost.Locale (también conocida como ICU con una interfaz más similar a C ++).
Hay algunos ejemplos en StackOverflow pero usan cadenas de caracteres anchas, y otras respuestas dicen que no debería usar cadenas de caracteres anchas para UTF-8.
El artículo incluido en (utf8everywhere) y las respuestas se aplican a Windows. El estándar C ++ requiere que wchar_t
ser lo suficientemente ancho para acomodar todas las unidades de código admitidas (32 bits de ancho) pero funciona perfectamente bien con UTF-8. En Windows, wchar_t
es UTF-16, pero si estás en Windows tienes más problemas que eso si vamos a ser honestos (es decir, su horrible API).
También parece que este problema puede ser muy “complicado” en el sentido de que la salida puede depender de la configuración regional del usuario.
Realmente no. Establezca la configuración regional dentro del código. Algunos programas como sort
no funciona correctamente si no establece la configuración regional dentro del shell, por ejemplo, por lo que la responsabilidad del usuario.
Esperaba usar algo como std :: toupper (), pero el uso no me queda claro porque parece que no solo estoy convirtiendo un carácter a la vez, sino todo un string.
El ejemplo de código usa iteradores. Si no quieres convertir todos los personajes, no lo hagas.
Además, este ejemplo de Ideone que reuní parece mostrar que toupper () de 0xc3b3 es solo 0xc3b3, que es un resultado inesperado. Llamar a setlocale a UTF-8 o ISO8859-1 no parece cambiar el resultado.
Tienes un comportamiento indefinido. El rango de unsigned char
es 255. 0xc3b3
mucho lo supera.
¡Me encantaría recibir una guía si pudiera arrojar algo de luz sobre lo que estoy haciendo mal o por qué mi pregunta / premisa es incorrecta!
Este ejemplo funciona perfectamente bien:
#include
#include
#include
int main()
std::setlocale(LC_CTYPE, "en_US.UTF-8"); // the locale will be the UTF-8 enabled English
std::wstring str = L"óó";
std::wcout << str << std::endl;
for (std::wstring::iterator it = str.begin(); it != str.end(); ++it)
*it = towupper(*it);
std::wcout << str << std::endl;
Salidas: ÓÓ
Estas características que no distinguen entre mayúsculas y minúsculas son definitivamente necesarias en las instalaciones de búsqueda.
Bueno, tengo la misma necesidad que se describió anteriormente y UTF8 es bastante fluido en la mayoría de las formas, pero las situaciones en mayúsculas y minúsculas no son tan buenas. ¿Parece que se saldrá de la lista de tareas pendientes cuando haya terminado? Porque ha sido en el pasado uno de los temas principales en la lista de tareas pendientes en tales casos. He estado parcheando el controlador de teclado de IBM 1984 antes de que IBM se enviara, pero había copias disponibles. También parcheó Displaywrite 1 y 3 (procesador de texto PC-DOS) antes de que IBM quisiera distribuirlo en Europa. Hice una gran cantidad de PC-DOS (CP850) y CP1252 (Windows) hacia y desde páginas de códigos EBCDIC nacionales en sistemas terminales de mainframe IBM 3270. Todos ellos tenían este tema de sensibilidad a mayúsculas y minúsculas en la lista de tareas pendientes. En todas las versiones nacionales de ASCII y las tablas de Windows CP1252 tenían un cambio entre 0x40-0x5F y 0x60-0x7F para cambiar entre mayúsculas y minúsculas (pero no PCDOS CP850), por 0x20.
¿Qué hacer al respecto?
Tolower () y toupper () no funcionarán en cadenas de caracteres múltiples UTF8, fuera de US-ASCII. Solo están trabajando con un byte. Pero un string La solución funcionaría, y hay soluciones para casi todo lo demás.
Los europeos occidentales tienen suerte
Bueno, el UTF8 puso el CP1252 (Windows 8bit / Latin1) como la primera tabla adicional, Latin-1 Supplement (bloque Unicode), como está. Esto significa que es posible cambiar las letras (C3XX) como el ASCII estadounidense normal. Ejemplo de código a continuación.
Griegos, rusos, islandeses y europeos del este no tienen tanta suerte
Para los islandeses, la Đ / đ - D con trazo (igual que el sonido de la palabra the) se acaba de perforar de CP1252.
Se podrían haber utilizado los conjuntos de caracteres ISO8 griegos, rusos y europeos del este (CP1253, CP1251 y CP1257) (ya que se utilizó directamente el latín CP1252). Entonces el simple cambio también habría funcionado. Pero, en cambio, alguien simplemente llenó la tabla de forma bastante aleatoria (como en el ASCII de 8 bits de PC-DOC).
Solo hay una solución de trabajo, la misma que para PC_DOS ASCII, hacer tablas de traducción. Lo haré para la próxima Navidad (cuando lo necesite mucho) pero le sugiero cómo hacerlo si alguien más tiene prisa.
Cómo hacer soluciones para griegos, rusos, islandeses y europeos del este
Haga diferentes tablas relacionadas con el primer byte diferente de la tabla UTF8 para Europa del Este, griego y cirílico en el código de programación. Llene las tablas con el segundo byte de las letras en sus posiciones de segundo byte UTF8 e intercambie las letras mayúsculas con el segundo byte correspondiente de las minúsculas, y haga otro al revés.
Luego, identifique qué primer byte se relaciona con cada tabla. De esa manera, el código de programación puede seleccionar la tabla correcta y simplemente leer la posición correcta y obtener los caracteres en mayúscula o minúscula necesarios. Luego modifique las funciones de mayúsculas y minúsculas a continuación (las que hice para Latin1), para usar tablas instaladas de cambio 0x20, para algunos primeros caracteres UTF8, donde se deben usar tablas. Funcionará sin problemas y las computadoras nuevas no tendrán problemas con la memoria y la energía.
Funciones relacionadas con mayúsculas y minúsculas UTF8 muestras de Latin1
Esto está funcionando, creo, lo probé en breve. Solo funciona en partes Latin-1 y USACII de UTF8.
unsigned char *StrToLwrUft8Latin1(unsigned char *pString)
char cExtChar = 0;
if (pString && *pString)
unsigned char *p = pString;
while (*p)
return pString;
unsigned char *StrToUprUft8Latin1(unsigned char *pString)
char cExtChar = 0;
if (pString && *pString)
unsigned char *p = pString;
while (*p)
return pString;
int StrnCiCmpLatin1(const char *s1, const char *s2, size_t ztCount)
unsigned char cExtChar = 0;
if (s1 && *s1 && s2 && *s2)
for (; ztCount--; s1++, s2++)
int iDiff = tolower((unsigned char)(*s1 & 0x7f)
+ cExtChar) - tolower((unsigned char)(*s2 & 0x7f) + cExtChar);
if (iDiff != 0
return 0;
int StrCiCmpLatin1(const char *s1, const char *s2)
return StrnCiCmpLatin1(s1, s2, (size_t)(-1));
char *StrCiStrLatin1(const char *s1, const char *s2)
if (s1 && *s1 && s2 && *s2)
char *p = (char *)s1;
size_t len = strlen(s2);
while (*p)
if (StrnCiCmpLatin1(p, s2, len) == 0)
return p;
p++;
return (0);
Agradecemos que quieras añadir valor a nuestra información tributando tu veteranía en las críticas.