2008-10-14 7 views
6

Cuál es la diferencia entre UTF y UCS.Uso de UTF en el código de C++

¿Cuáles son las mejores formas de representar conjuntos de caracteres no europeos (usando UTF) en cadenas de C++? Me gustaría conocer sus recomendaciones para:

  • Representación interna dentro del código
    • Para la manipulación de cadenas en tiempo de ejecución
    • Para utilizar la cadena para fines de visualización.
  • mejor representación de almacenamiento (es decir En archivo)
  • mejor en formato de transporte de alambre (transferencia entre la aplicación que puede ser en diferentes arquitecturas y tienen una configuración regional estándar diferente)

Respuesta

8

Cuál es la diferencia entre UTF y UCS.

Las codificaciones de UCS son de ancho fijo, y están marcadas por la cantidad de bytes que se utilizan para cada carácter. Por ejemplo, UCS-2 requiere 2 bytes por carácter. Los caracteres con puntos de código fuera del rango disponible no se pueden codificar en una codificación UCS.

Las codificaciones UTF son de ancho variable, y están marcadas por el número mínimo de bits para almacenar un carácter. Por ejemplo, UTF-16 requiere al menos 16 bits (2 bytes) por carácter. Los caracteres con grandes puntos de código se codifican utilizando una mayor cantidad de bytes: 4 bytes para los caracteres astrales en UTF-16.

  • representación interna dentro del código
  • mejor representación de almacenamiento (es decir, En archivo)
  • mejor en formato de transporte de alambre (transferencia entre la aplicación que pueden estar en diferentes arquitecturas y tienen una configuración regional estándar diferente)

Para los sistemas modernos, la codificación más razonable de almacenamiento y transporte es UTF-8. Existen casos especiales en los que otros podrían ser apropiados: UTF-7 para servidores de correo antiguos, UTF-16 para editores de texto mal escritos, pero UTF-8 es el más común.

La representación interna preferida dependerá de su plataforma. En Windows, es UTF-16. En UNIX, es UCS-4. Cada uno tiene sus puntos buenos:

  • Las cadenas UTF-16 nunca utilizan más memoria que una cadena UCS-4. Si almacena muchas cadenas grandes con caracteres principalmente en el plano básico multilingüe (BMP), UTF-16 requerirá mucho menos espacio que UCS-4. Fuera del BMP, usará la misma cantidad.
  • UCS-4 es más fácil de razonar. Debido a que los caracteres UTF-16 pueden dividirse en varios "pares de sustitución", puede ser un desafío dividir o representar correctamente una cadena. El texto de UCS-4 no tiene este problema. UCS-4 también actúa de forma similar al texto ASCII en matrices "char", por lo que los algoritmos de texto existentes se pueden portar fácilmente.

Finalmente, algunos sistemas usan UTF-8 como formato interno. Esto es bueno si necesita interoperar con sistemas existentes basados ​​en ASCII o ISO-8859 porque los bytes NULL no están presentes en el medio del texto UTF-8, están en UTF-16 o UCS-4.

+1

No, las codificaciones UTF no son siempre de ancho variable (piénsese en UTF-32, por ejemplo). – bortzmeyer

+0

Utf-32 puede usar un ancho fijo para cada punto de código, pero * creo * todavía puede tener (y necesita aceptar y normalizar a un punto de código) múltiples puntos de código (cuando tiene caracteres combinados) que representan un char/glifo completo. Si es así, UTF-32 no es mucho mejor que UTF-16. – Shadow2531

+1

@bortzmeyer: UTF-32 es realmente solo UCS-4 con algunas restricciones adicionales. Honestamente, nunca he visto UTF-32 usado * en ninguna parte *, así que tiendo a ignorarlo. –

0

UTC está coordinado Hora universal, no un juego de caracteres (no encontré ningún juego de caracteres llamado UTC).

Para la representación interna, es posible que desee utilizar wchar_t para cada carácter, y std :: wstring para cadenas. Usan exactamente 2 bytes para cada personaje, por lo que la búsqueda y el acceso aleatorio serán rápidos.

Para el almacenamiento, si la mayor parte de los datos no son ASCII (es decir, código de> = 128), es posible que desee utilizar UTF-16, que es casi lo mismo que serializado wstring y wchar_t.

Dado que UTF-16 puede ser pequeño endian o big endian, para el transporte de cables, intente convertirlo a UTF-8, que es independiente de la arquitectura.

+0

El tamaño de wchar_t (y, por lo tanto, internamente no es wstring) no está definido He visto versiones de 2 y 4 bytes. Por qué UTS-16 para almacenamiento pero UTF-8 para archivos (los archivos pueden guardarse en una máquina y cargarse en otra). Quiero entender por qué tomó la decisión y la elección. –

+0

http://en.wikipedia.org/wiki/Universal_Character_Set –

+0

@Martin: UTF-16 no se puede procesar con herramientas ASCII existentes porque muchos bytes son 0, lo que hace que las funciones por byte crean que se ha llegado al terminador NULL. –

2

que sugeriría:

  • Para la representación en el código, wchar_t o equivalente.
  • Para representación de almacenamiento, UTF-8.
  • Para la representación del cable, UTF-8.

La ventaja de UTF-8 en situaciones de almacenamiento y cableado es que la permanencia de la máquina no es un factor. La ventaja de utilizar un carácter de tamaño fijo como wchar_t en el código es que puede averiguar fácilmente la longitud de una cadena sin tener que escanearla.

+0

wchar_t: ¿Pero qué codificación? ¿Estás sugiriendo UTF-16 internamente? –

+0

En muchas plataformas Unix, wchar_t es de 32 bits, por lo que es fácil. En las plataformas donde wchar_t es de 16 bits, sí, UTF-16 sería el camino a seguir. –

+0

Martin: Revertí la edición porque usar wchar_t no implica UTF-16 - en UNIX, sizeof (wchar_t) == 4. –

0

En representación interna dentro del código, es mejor que hace esto para ambos caracteres europeos y no europeos:

\ uNNNN

caracteres en el rango \ u0020 a \ u007E, y un poco de espacios en blanco (por ejemplo, final de línea) se pueden escribir como caracteres ordinarios. Algo por encima de \ u0080, si lo escribe como un personaje ordinario, entonces compilará solo en su página de códigos (por ejemplo, OK en Francia, pero irrumpir en Rusia, OK en Rusia pero irrumpir en Japón, OK en China pero irrumpir en los EE. UU., Etc. .).

Cuestiones relacionadas