2009-10-07 10 views
11

Cuanto más trabajo con las facetas de configuración regional de C++, más entiendo, están rotas.¿Hay alguna actualización del soporte de localización en C++ 0x?

  • std::time_get - no es simétrica con std::time_put (como en C strftime/strptime) y no permite el análisis fácil de veces con marcas de AM/PM.
  • I discovered recientemente ese formato de número simple puede producir UTF-8 ilegal bajo ciertas configuraciones regionales (como ru_RU.UTF-8).
  • std::ctype es muy simplista, suponiendo que a la parte superior/inferior se puede hacer en base por carácter (la conversión de mayúsculas y minúsculas puede cambiar el número de caracteres y depende del contexto).
  • std::collate - no es compatible con la potencia de compaginación (mayúsculas y minúsculas o insensible).
  • No hay forma de especificar la zona horaria diferente de la zona horaria global en el formato de hora.

Y mucho más ...

  • ¿Alguien sabe si se espera que los cambios en las facetas estándar en C++ 0x?
  • ¿Hay alguna forma de resaltar la importancia de dichos cambios?

Gracias.

EDIT: aclaraciones en caso de que el enlace no es accesible:

std::numpunct define el separador de miles como char. Por lo tanto, cuando el separador en U + 2002 - diferente tipo de espacio no puede ser reproducido como un solo carácter en UTF-8 sino como una secuencia de bytes múltiples.

En C API struct lconv define el separador de miles como cadena y no sufre este problema. Entonces, cuando intenta formatear números con separadores fuera de ASCII con configuración regional UTF-8, se produce un UTF-8 no válido.

Para reproducir este error de escritura 1234 para std: ostream con impregnada ru_RU.UTF-8 local

Edit2: he de reconocer que POSIX C API de localización funciona mucho más suave:

  • Hay inversa de strftime - - strptime (strftime hace lo mismo que std::time_put::put)
  • No hay problemas con el formato de número debido al punto que mencioné anteriormente.

Sin embargo, todavía es para ser perfeccionado.

Edit3: Según las últimas notas acerca de C++ 0x me puede ver que std::time_get::get - similar a strptime y enfrente de std::time_put::put.

+0

Parece ser que tiene suerte de que funcione la configuración estándar. Nunca he tenido éxito con MingW. – UncleBens

+0

El único enlace en su respuesta está roto y no funciona no abierto (no es sorprendente dado que es '.no-ip.info', supongo, pero como es una parte de la pregunta, es posible que desee colocarlo en otro lugar para que sea accesible). –

+0

Mingw no admite ninguna configuración regional aceptar C/POSIX. Sin embargo, en linux la compatibilidad con locale es muy buena. BTW C library API es mucho más limpio, mejor diseñado y generalmente funciona mucho más uniformemente. Pero ... POSIX API permite solo una configuración regional por proceso que es bastante limitada. – Artyom

Respuesta

1

std::numpunct es una plantilla. Todas las especializaciones intentan devolver el carácter separador decimal.Obviamente, en cualquier localidad donde ese sea un personaje ancho, debe usar std::numpunct<wchar_t>, ya que la especialización <char no puede hacer eso.

Dicho esto, C++ 0x está casi hecho. Sin embargo, si continúan las buenas mejoras, es probable que el comité de C++ comience con C++ 1x. Es muy probable que el comité de ISO C++ acepte su ayuda, si se ofrece a través de su organización nacional miembro de ISO. Veo que Pavel Minaev sugirió un Informe de Defecto. Eso es técnicamente posible, pero los problemas que describes son en general limitaciones de diseño. En ese caso, el curso de acción más confiable es diseñar una biblioteca de Boost para esto, pasar la revisión de Boost, enviarla para su inclusión en el estándar y participar en las reuniones de ISO C++ para tratar cualquier problema que surja allí.

+0

"se debe utilizar std :: numpunct ", wchar_t es una de las maneras de proporcionar el punto Unicode ". ¿Qué pasa si se coloca tal punto fuera de BMP y sizeof == (wchar_t) 2? ¿Qué pasa si tales la separación consta de más de un carácter. ¡Este es exactamente el mismo problema! Además, cuando usa la configuración regional UTF-8, debe esperar que los caracteres sean más amplios que 1 byte. La solución correcta es proporcionar (CharT const *) resultado de retorno de CharT. En cualquier caso, cuando escribe un programa simple que imprime números, espera que maneje Unicode correctamente, como esto se hace en la localización C. – Artyom

+0

El diseño de 'wchar_t' es tal que un solo' wchar_t' puede contener cualquier carácter admitido por la implementación. Por esa razón, una implementación con 16 bits wchar_t no puede admitir todos los caracteres Unicode 5.0. Tendría que elegir un subconjunto admitido, como el BMP. No existe tal cosa en ISO C++ como una "cadena multi-wchar_t". Sin embargo, una implementación es libre de definir un '__char16' o un' __char32' y especializar 'std :: numpunct <>' para ellos. – MSalters

+0

"una implementación con 16 bits wchar_t no puede admitir todo Unicode 5.0" No puede admitir todo Unicode 2.0 donde se introdujeron los primeros caracteres sustitutos. "No hay tal cosa en ISO C++ como una" cadena multi-wchar_t "" - ¿Qué pasa con UTF-16? 'wchar_t const *' está perfectamente bien. Eche un vistazo allí: http://linux.die.net/man/7/locale. El separador de miles se representa como 'char *' en 'struct lconv', por lo que no hay problema para representar cualquier carácter Unicode dado el entorno local UTF-8. – Artyom

4

Estoy de acuerdo con usted, C++ carece de la compatibilidad adecuada i18n.

¿Alguien sabe si se esperan cambios en facetas estándar en C++ 0x?

Es demasiado tarde en el juego, por lo que probablemente no.

¿Hay alguna forma de resaltar la importancia de dichos cambios?

Soy muy pesimista sobre esto.

Cuando se le preguntó directamente, Stroustrup afirmó que no ve ningún problema con el estado actual. Y otro de los grandes chicos de C++ (autor del libro y todo) ni siquiera se dio cuenta de que wchar_t puede ser un byte, si lees el estándar.

Y algunos subprocesos en el impulso (que parece conducir la dirección en el futuro) muestran tan poca comprensión sobre cómo funciona esto que es francamente aterrador.

C++ 0x apenas agregó algunos tipos de datos de caracteres Unicode, al final del juego y después de mucha lucha. No estoy conteniendo la respiración por más demasiado pronto.

Supongo que la única posibilidad de ver algo mejor es si alguien realmente bueno/respetado en los mundos i18n y C++ se involucra directamente con la próxima versión del estándar. Sin embargo, no hay idea de quién podría ser :-(

Cuestiones relacionadas