No soy capaz de entender las diferencias entre std::string y std::wstring. Sé wstring compatible con una amplia caracteres tales como caracteres Unicode. Tengo las siguientes preguntas:

  1. Cuando debo usar std::wstring más de std::string?
  2. Puede std::string contener todo el conjunto de caracteres ASCII, incluyendo los caracteres especiales?
  3. Es std::wstring apoyado por todos los compiladores de C++?
  4. ¿Qué es exactamente un «carácter«?
  • El ASCII charachter conjunto no tiene una gran cantidad de «especiales», los personajes, el más exótico es probablemente ` (acento grave). std::string puede contener aproximadamente 0.025% de todos los caracteres Unicode (generalmente, 8 bit char)
  • Si por «especial» te refieres a los personajes de 128 a 255, que dependen de la norma utilizada, entonces sí son compatibles.
  • Buena información acerca de los distintos personajes y que tipo de uso se puede encontrar aquí: programmers.stackexchange.com/questions/102205/…
  • Bueno, y ya que estamos en el 2012, utf8everywhere.org fue escrito. Casi todas las preguntas acerca de los derechos y agravios con C++/Windows.
  • std::string puede contener el 100% de todos los caracteres Unicode, incluso si CHAR_BIT es 8. Depende de la codificación de std::string, el cual puede ser UTF-8 en el nivel de sistema (como casi todas partes, excepto para windows) o en su nivel de aplicación. Nativo estrecho de codificación no admite Unicode? No hay problema, simplemente no lo uso, uso de UTF-8 en lugar.
  • Sobre WinAPI base de la aplicación es muy incómodo de usar std::string porque pierdes en las conversiones (UNICODE <-> ANSI), que sucede muy a menudo. Por supuesto, usted puede utilizar ANSI alias de WinAPI funciones, pero sólo son macros que convertir implícitamente su ANSI codificado argumentos para UNICODE queridos y de la llamada «real» código de la API de que es TODO lo basan en UNICODE (consulte J. Richter «Programación de Windows» 5ª ed.)
  • Gran lectura sobre este tema: utf8everywhere.org

InformationsquelleAutor | 2008-12-31

12 Comentarios

  1. 950

    string? wstring?

    std::string es un basic_string de plantilla en un char, y std::wstring en un wchar_t.

    char vs wchar_t

    char se supone mantener un carácter, por lo general una de caracteres de 8 bits.

    wchar_t se supone que para sostener una gran carácter, y entonces, las cosas se ponen difíciles:

    En Linux, un wchar_t es de 4 bytes, mientras que en Windows, es de 2 bytes.

    Lo que acerca de Unicode, entonces?

    El problema es que ni char ni wchar_t está directamente ligada a unicode.

    En Linux?

    Echemos un sistema operativo Linux: Mi sistema Ubuntu ya es unicode. Cuando yo trabajo con un char cadena, es de forma nativa codificados en UTF-8 (es decir, Unicode cadena de caracteres). El código siguiente:

    #include <cstring>
    #include <iostream>
    int main(int argc, char* argv[])
    {
    const char text[] = "olé" ;
    std::cout << "sizeof(char)    : " << sizeof(char) << std::endl ;
    std::cout << "text            : " << text << std::endl ;
    std::cout << "sizeof(text)    : " << sizeof(text) << std::endl ;
    std::cout << "strlen(text)    : " << strlen(text) << std::endl ;
    std::cout << "text(ordinals)  :" ;
    for(size_t i = 0, iMax = strlen(text); i < iMax; ++i)
    {
    std::cout << " " << static_cast<unsigned int>(
    static_cast<unsigned char>(text[i])
    );
    }
    std::cout << std::endl << std::endl ;
    //- - - 
    const wchar_t wtext[] = L"olé" ;
    std::cout << "sizeof(wchar_t) : " << sizeof(wchar_t) << std::endl ;
    //std::cout << "wtext           : " << wtext << std::endl ; <- error
    std::cout << "wtext           : UNABLE TO CONVERT NATIVELY." << std::endl ;
    std::wcout << L"wtext           : " << wtext << std::endl;
    std::cout << "sizeof(wtext)   : " << sizeof(wtext) << std::endl ;
    std::cout << "wcslen(wtext)   : " << wcslen(wtext) << std::endl ;
    std::cout << "wtext(ordinals) :" ;
    for(size_t i = 0, iMax = wcslen(wtext); i < iMax; ++i)
    {
    std::cout << " " << static_cast<unsigned int>(
    static_cast<unsigned short>(wtext[i])
    );
    }
    std::cout << std::endl << std::endl ;
    return 0;
    }

    salidas el siguiente texto:

    sizeof(char)    : 1
    text            : olé
    sizeof(text)    : 5
    strlen(text)    : 4
    text(ordinals)  : 111 108 195 169
    sizeof(wchar_t) : 4
    wtext           : UNABLE TO CONVERT NATIVELY.
    wtext           : ol�
    sizeof(wtext)   : 16
    wcslen(wtext)   : 3
    wtext(ordinals) : 111 108 233

    Verás el «olé» de texto en char es realmente construido por cuatro caracteres: 110, 108, 195 y 169 (sin contar la cola cero). (Voy a dejar de estudiar la wchar_t código como un ejercicio)

    Así, cuando se trabaja con un char en Linux, usted debe por lo general terminan usando Unicode sin siquiera saberlo. Y como std::string trabaja con char, así std::string ya está en unicode listo.

    Nota que std::string, como la C de la cadena de la API, se considere el «olé» cadena de 4 caracteres, no tres. Así que usted debe ser cauteloso cuando truncar/jugando con los caracteres unicode debido a una combinación de caracteres que está prohibido en UTF-8.

    En Windows?

    En Windows, esto es un poco diferente. Win32 tenía que apoyar un montón de aplicaciones que trabajan con char y en diferentes los juegos de caracteres/páginas de códigos producido en todo el mundo, antes de la llegada de Unicode.

    Por lo que su solución fue interesante: Si una aplicación funciona con char, entonces el char son las cadenas de caracteres codificados/impreso/muestra en las etiquetas de la GUI con el local charset/página de códigos en la máquina. Por ejemplo, «olé» sería «olé» en francés-localizada de Windows, pero sería algo diferente en un cirílico-localizada de Windows («olй» si utiliza Windows-1251). Por lo tanto, histórica «apps» generalmente todavía funcionan de la misma manera.

    Para Unicode de aplicaciones basadas en Windows utiliza wchar_t, que es de 2-bytes de ancho, y está codificado en UTF-16, que está en formato Unicode en 2 bytes (o, al menos, la mayoría compatible UCS-2, que es casi la misma cosa IIRC).

    Aplicaciones utilizando char se dice «multibyte» (porque cada glifo se compone de uno o más chars), mientras que las aplicaciones utilizando wchar_t se dice «widechar» (porque cada glifo se compone de uno o dos wchar_t. Ver MultiByteToWideChar y WideCharToMultiByte Win32 conversión de la API para obtener más información.

    Por lo tanto, si usted trabaja en Windows, usted el mal quiere utilizar wchar_t (a menos que utilice un marco de clandestinidad que, como GTK+ o QT…). El hecho es que detrás de las escenas, Windows funciona con wchar_t cadenas, por lo que incluso histórico solicitudes tendrán sus char cadenas convertido en wchar_t cuando se utiliza la API como SetWindowText() (bajo nivel de la función de la API para establecer la etiqueta de una Win32 GUI).

    De los problemas de memoria?

    UTF-32 es de 4 bytes por cada uno de los personajes, así que no hay mucho para agregar, si tan sólo que un texto UTF-8 y UTF-16 de texto siempre use menos o la misma cantidad de memoria que un UTF-32 texto (y generalmente menos).

    Si hay un problema con la memoria, entonces usted debe saber que para la mayoría de las lenguas occidentales, texto UTF-8 se utiliza menos memoria que el mismo UTF-16.

    Todavía, para otros idiomas (chino, japonés, etc.), la memoria utilizada va a ser la misma, o un poco más grande para UTF-8 que para UTF-16.

    Todos en todos, UTF-16 sobre todo el uso de 2 y de vez en cuando 4 bytes por cada uno de los personajes (a menos que usted está tratando con algún tipo de lenguaje esotérico de los glifos (Klingon? De elfo?), mientras UTF-8 va a pasar de 1 a 4 bytes.

    Ver http://en.wikipedia.org/wiki/UTF-8#Compared_to_UTF-16 para obtener más información.

    Conclusión

    1. Cuando debo usar std::wstring más de std::string?

      En Linux? Casi nunca (§).

      En Windows? Casi siempre (§).

      En la cruz-plataforma de código? Depende de su caja de herramientas…

      (§) : a menos que se utilice un kit de herramientas/marco dicen lo contrario

    2. Puede std::string sostener todo el conjunto de caracteres ASCII, incluyendo caracteres especiales?

      Aviso: Un std::string es adecuado para la celebración de un ‘binario’ buffer, donde un std::wstring no es!

      En Linux? Sí.

      En Windows? Sólo los caracteres especiales disponibles para la configuración regional actual del usuario de Windows.

      Editar (Después de un comentario de Johann Gerell):

      un std::string será suficiente para controlar todos charbasado en cadenas (cada char es un número de 0 a 255). Pero:

      1. ASCII es que se supone que van de 0 a 127. Mayor chars NO son ASCII.
      2. un char de 0 a 127 se celebrará correctamente
      3. un char de 128 a 255 tendrá una significación dependiendo de su codificación unicode y no unicode, etc.), pero va a ser capaz de mantener todas Unicode glifos como están codificados en UTF-8.
    3. Es std::wstring apoyado por casi todos los compiladores de C++?

      Su mayoría, con la excepción de GCC en base a los compiladores que son portado a Windows.

      Funciona en mi g++ 4.3.2 (bajo Linux), y he usado Unicode de la API de Win32 desde Visual C++ 6.

    4. ¿Qué es exactamente un carácter ancho?

      En C/C++, es un tipo de carácter escrito wchar_t que es más grande que la simple char tipo de carácter. Se supone que debe ser utilizado para poner en el interior de los personajes, cuyos índices (como Unicode glifos) son mayores que 255 (o 127, función…).

    • Hum. Yo no sabía que windows no siga la especificación POSIX en este sentido. POSIX dice que un wchar_t debe ser capaz de representar a los «distintos caracteres anchos códigos para todos los miembros de la mayor conjunto de caracteres especificado entre los locales soportadas por el entorno de compilación».
    • Tal vez wchar_t iba a ser suficiente para manejar todas las UCS-2 chars (la mayoría de UTF-16 caracteres) antes de la llegada de UTF-16… O tal vez Microsoft tenía otras prioridades de POSIX, como dar fácil acceso a Unicode sin modificar el codepaged uso de char en Win32.
    • Nota la definición de wchar_t, citado en Wikipedia: en.wikipedia.org/wiki/Wchar_t … al Parecer, whcar_t en Windows de la siguiente manera lo que se le preguntó por Unicode… ^_^ …
    • Su respuesta explica muy bien las diferencias entre las dos alternativas. Comentario: UTF-8 puede tomar 1-6 bytes y no 1-4 como usted escribió. También me gustaría ver a la gente de opinión entre las dos alternativas.
    • Sbarnea: UTF-8 podría tomar 1-6 bytes, pero al parecer, la norma limita a 1-4. Consulte en.wikipedia.org/wiki/UTF8#Description para más información.
    • Compilar y ejecutar el código en Mac OS X da el mismo resultado que en su máquina linux.
    • Plaschg : Gracias por la info. Esto no es inesperado, ya que el MacOS X es un Unix, por lo que esto parece natural que se fue por el camino «char es un UTF-8» para que soporte Unicode… AFAIK, las únicas razones por las que Windows no siga el mismo camino fue a continuar el apoyo para la pre-conjunto de caracteres Unicode basado en antiguas aplicaciones.
    • UTF-8 no puede tomar de 6 bytes. Precisamente porque la norma limita a 4 bytes. El estándar define las cosas, así que 6 bytes significa que no es UTF-8 ya que, por definición.
    • Nita : UTF-8 cannot take 6 bytes. Exactly because the the standard limits it to 4 bytes. . Estoy de acuerdo. Estoy de acuerdo tanto con el que hice ya a escribir en un comentario anterior : @Sorin Sbarnea: UTF-8 could take 1-6 bytes, but apparently the standard limits it to 1-4. … ^_^ … supongo que el punto de mi comentario era para recordarle que la limitación a 4 era artificial, que la codificación que se utiliza UTF-8 puede soportar hasta 6 bytes 1 byte, char, incluso si la norma decidido limitar a 4.
    • Quiero hacer #include <stdlib.h> std::wstring ws; lr += wchar(2591); /*el 25% de sombra de caracteres */ std::wcout<<lr; pero esto se me vacía de salida. ¿CÓMO puedo poner en un gran unicode char número en un wstring y salida?
    • Michaels : Usted está tratando de salida el carácter x0A1F (Gurmukhi). un wchar_t es capaz de contener ese carácter, por lo que su cadena es correcta. Si el wcout de salida no es correcta, puede ser debido a la fuente a usar para la salida de la consola no está preparada para el Gurmukhi símbolos ( unicode.org/charts/PDF/U0A00.pdf )
    • Mientras que este ejemplo produce diferentes resultados en Linux y en Windows el programa C++ que contiene la aplicación definida por el comportamiento en cuanto a si olè es codificado como UTF-8 o no. Aún más, la razón por la que no de forma nativa stream wchar_t * a std::cout es porque los tipos son incompatibles, resultando en un mal formada programa y no tiene nada que ver con el uso de codificaciones. Vale la pena señalar que si usted utiliza std::string o std::wstring depende de su propia preferencia de codificación en lugar de la plataforma, especialmente si usted quiere que su código para ser portátil.
    • este ejemplo produce diferentes resultados en Linux y en Windows el programa C++ que contiene la aplicación definida por el comportamiento en cuanto a si olè es codificado como UTF-8 o no. : Sí. De hecho, el objetivo era mostrar que. Further more, the reason you cannot natively stream wchar_t * to std::cout is because the types are incompatible resulting in an ill-formed program and it has nothing to do with the use of encodings. : De hecho. Me estaba dando las múltiples combinaciones, y si no es posible, explicando por qué en el código, para completura’ bien, no haciendo que el punto de sugerir…
    • Leidegren : It's worth pointing out that whether you use std::string or std::wstring depends on your own encoding preference rather than the platform : De Hecho. Pero entonces, si las restricciones son «el uso de unicode, aunque no con 4 bytes para cada personaje», la plataforma de casi limita sus opciones, es decir, std::wstring en Windows, y std::string en Linux… (Usted podría tratar de usar UTF-8 std::string en Windows, pero luego, su UTF-8 cuerdas no ser entendido por la WinAPI utilizando char * caracteres.)
    • Sea cual sea la plataforma soporta es totalmente arbitrario y fuera de lugar. Si almacena todas las cadenas internamente como UTF-8 en Windows tendrás que convertirlos a ANSI o UTF-16 y llamar a la correspondiente función de Win32, pero si usted sabe que su UTF-8 cuerdas son simplemente cadenas de caracteres ASCII que usted no tiene que hacer nada. La plataforma no dicta cómo las cadenas se utilizan tanto como las circunstancias.
    • Leidegren : por supuesto, la plataforma dicta cómo utilizar las cuerdas. En Windows, no tienes elección: char cadenas tienen una página de códigos específica de codificación, por lo que como utilice el std::string, ya sea por escrito de correo, o mediante la página de códigos funciones específicas, debe ser decidido. Como para std::wstring, a menos que utilice una interfaz de conversión, usted sabe que la codificación debe ser la versión de Windows de UTF-16 (la última vez que revisé, fue UCS-2), por lo tanto como interpretar a los personajes en ese contexto. Como yo lo veo, esto es «como«, no «circunstancias«. Pero no perdamos tiempo en el vocabulario…
    • Windows utiliza UTF-16 y lo han sido durante bastante tiempo, las versiones más antiguas de Windows hizo uso de UCS-2, pero este no es el caso, no más. Mi único problema aquí es la conclusión a la que std::wstring debe ser utilizado en Windows porque es un mejor ajuste para el Unicode de la API de Windows que creo que es una falacia. Si su única preocupación era la llamada en el Unicode de la API de Windows y no el cálculo de referencias de cadenas, a continuación, seguro, pero yo no compre esta como el caso general.
    • Juan Leidegren : If your only concern was calling into the Unicode Windows API and not marshalling strings then sure : Entonces, estamos de acuerdo. Estoy de codificación en C++, no JavaScript. Evitar el inútil de clasificación o cualquier otra potencialmente costosa de procesamiento en tiempo de ejecución cuando se puede hacer en tiempo de compilación está en el corazón de ese idioma. La codificación contra WinAPI y el uso de std::string es sólo una injustificada de desperdiciar recursos en tiempo de ejecución. Te resulta falaz, y está bien, ya que es su punto de vista. Mi cuenta es de que no voy a escribir código con pessimization en Windows, simplemente, porque se ve mejor desde el lado Linux.
    • consulte este gran respuesta por qué el POSIX requisito (de hecho es C++ requisito) no violan el uso de la variable codificación de longitud.
    • Como una pequeña corrección, codificación UTF-16 puede tomar cualquiera de los 2 O 4 bytes por carácter. (consulte unicode.org/faq/utf_bom.html#gen6)
    • De hecho. La primera vez que hablo de caracteres anchos en Windows, puedo describir la forma en que Windows no era muy claro (al menos, para mí) acerca de cómo se manejaba la «unicode» (¿qué es la UCS-2 o UTF-16?). El segundo tiempo, escribo sobre el tamaño de un personaje: «todo en Todos, UTF-16 sobre todo el uso de 2 bytes por cada uno de los personajes (a menos que usted está tratando con algún tipo de lenguaje esotérico de los glifos (Klingon? De elfo?), mientras UTF-8 va a pasar de 1 a 4 bytes.», que es más o menos lo que estás diciendo (la palabra clave «sobre todo»). Me imagino lo que debe ser claro en mi respuesta es Windows postura sobre el tema.
    • interesante tener en cuenta que si usted hace una cout antes de la wcout los caracteres unicode no impresión con wcout. Sin embargo, si usted comienza con wcout, el cout‘s no imprime nada, y todos unicode impresiones de impresión correctamente. Casi como si algún estado interno se mantiene en la libs?
    • Sólo una nota: Uno de esos exóticos idiomas es chino por cierto. Por lo tanto la república popular de china decidió hacer de soporte para algunos puntos de codificación de fuera del BMP obligatoria hace bastante tiempo.
    • «cuando se trabaja con un char en Linux, usted debe por lo general terminan usando Unicode sin siquiera saberlo. Y como std::string trabaja con char, de modo std::string ya está en unicode listo.» – esto debe de ir con una advertencia de GRAN tamaño «nunca truncate, límite, tomar char-en» las cadenas. Esto puede ser entendido a partir de la respuesta completa, pero debe ser hecho súper claro.
    • Lo que hace de este un wchar_t[]?
    • {0x42, 0 x 65, 0x6E, 0x6A, 0x61, 0x6D, 0xED, 0x6E, 0x20, 0x70, 0x69, 0x64, 0x69, 0xF3, 0x20, 0x75, 0x6E, 0x61, 0x20, 0x62, 0 x 65, 0x62, 0x69, 0x64, 0x61, 0x20, 0x64, 0 x 65, 0x20, 0x6B, 0x69, 0x77, 0x69, 0x20, 0x79, 0x20, 0x66, 0x72, 0 x 65, 0x73, 0x61, 0x3B, 0x20, 0x4E, 0x6F, 0xE9, 0x2C, 0x20, 0x73, 0x69, 0x6E, 0x20, 0x76, 0 x 65, 0x72, 0x67, 0xFC, 0 x 65, 0x6E, 0x7A, 0x61, 0x2C, 0x20, 0x6C, 0x61, 0x20, 0x6D, 0xE1, 0x73, 0x20, 0 x 65, 0x78, 0x71, 0x75, 0x69, 0x73, 0x69, 0x74, 0x61, 0x20, 0x63, 0x68, 0x61, 0x6D, 0x70, 0x61, 0xF1, 0x61, 0x20, 0x64, 0 x 65, 0x6C, 0x20, 0x6D, 0 x 65, 0x6E, 0xFA, 0x2E, 0x00};
    • Nada, eso es sólo una secuencia de bytes. No puede ser interpretado como UTF8, pero parece interpretable como UTF16. O cualquiera de las miles de páginas de código.
    • Me doy cuenta de este hilo de comentarios es tan antigua como el tiempo mismo, pero insistiendo en la coincidencia de WinAPI formato de cadena por razones de rendimiento es simplemente tonto. El coste de las llamadas a la API en sí minimizará los costos de conversión; el costo de rendimiento de la extra de almacenamiento requerido para UTF-16 cadenas probablemente negar cualquier posibilidad de la conversión de los beneficios; y si usted se comunica con otras Api, es probable que necesite para hacer las conversiones de todos modos. Consulte utf8everywhere.org/#faq.cvt.perf para ver un ejemplo.
    • Para un programa de windows, que obtiene su entrada codificación UTF-8, cadenas, no hay ningún punto en la conversión de everyhing a wchar_t. Sólo se convierte en interacción directa con WinAPI. Mientras el compilador trabaja con codificación UTF-8, no veo el punto de preferir wchar_t más de char. Como de costumbre, depende de los requisitos.
    • Hoy en día, Windows 10, por fin permite a UTF-8 como local del conjunto de caracteres…

  2. 59

    Me recomiendan evitar std::wstring en Windows o en otros lugares, excepto cuando sea requerido por la interfaz, o en cualquier lugar cerca de llamadas a API de Windows y de la respectiva codificación de las conversiones como un azúcar sintáctico.

    Mi punto de vista se resume en http://utf8everywhere.org de la que soy co-autor.

    A menos que su aplicación API-call-centric, por ejemplo, principalmente de interfaz de usuario de la aplicación, la sugerencia es para almacenar cadenas Unicode en std::string y codificados en UTF-8, la realización de la conversión de cerca de llamadas a la API. Los beneficios descritos en el artículo superan la aparente molestia de conversión, especialmente en aplicaciones complejas. Esto es doblemente para multi-plataforma y desarrollo de la biblioteca.

    Y ahora, respondiendo a sus preguntas:

    1. Un par de razones débiles. Existe, por razones históricas, donde widechars se creía que la forma correcta de apoyo a Unicode. En la actualidad se utiliza la interfaz Api que prefieren UTF-16 cuerdas. Yo los uso sólo en las inmediaciones de tales llamadas a la API.
    2. Esto no tiene nada que ver con std::string. Puede contener cualquier codificación que usted pone en ella. La única pregunta es cómo Que el tratamiento de su contenido. Mi recomendación es UTF-8, por lo que será capaz de mantener todos los caracteres Unicode correctamente. Es una práctica común en Linux, pero creo que los programas de Windows debería hacerlo también.
    3. No.
    4. Carácter ancho es confuso nombre. En los primeros días de Unicode, existía la creencia de que un carácter puede ser codificados en dos bytes, por lo tanto el nombre. Hoy en día, es sinónimo de «cualquier parte del carácter que es de dos bytes de largo». UTF-16 es visto como una secuencia de dichos bytes pares (aka caracteres Anchos). Una de caracteres en UTF-16 toma uno o dos pares.
  3. 37

    Así, cada lector de aquí ahora debe tener una comprensión clara acerca de los hechos, la situación. Si no, entonces usted debe leer paercebal extraordinariamente respuesta integral [por cierto: ¡gracias!].

    Mi pragmatical conclusión es sorprendentemente simple: todo lo que C++ (STL) «codificación de caracteres» cosas es sustancialmente roto e inútil. La culpa es de Microsoft o no, que no va a ayudar de todos modos.

    Mi solución, después de una investigación en profundidad, tanta frustración y la consecuente experiencias es la siguiente:

    1. aceptar que usted tiene que ser responsable de su propio para la codificación y conversión de cosas (y verás que mucho de eso es bastante trivial)

    2. usar std::string para cualquier codificado en UTF-8 cuerdas (sólo un typedef std::string UTF8String)

    3. aceptar que tal UTF8String objeto es solo un tonto, pero es barato contenedor. Nunca jamás de acceso y/o manipular los personajes en ella directamente (sin buscar, reemplazar, y así sucesivamente). Usted podría, pero realmente, realmente, realmente no quiero perder el tiempo de la escritura de algoritmos para la manipulación de texto multi-cadenas de bytes! Incluso si la otra persona ya hizo cosas tan estúpidas, no hagas eso! Vamos a ser! (Bueno, hay escenarios donde tiene sentido… solo uso la UCI de la biblioteca para ellos).

    4. usar std::wstring para UCS-2 cadenas codificadas (typedef std::wstring UCS2String) – esto es un compromiso, y una concesión para el desastre en que la API de WIN32 introducido). UCS-2 es suficiente para la mayoría de nosotros (más sobre esto más adelante…).

    5. uso UCS2String instancias cada vez que un carácter por carácter se requiere acceso (leer, manipular, y así sucesivamente). Cualquier basada en el personaje de procesamiento debe hacerse en un NO-multi-byte representación. Es simple, rápido, fácil.

    6. agregar dos funciones de utilidad para convertir de nuevo & vuelta entre UTF-8 y UCS-2:

      UCS2String ConvertToUCS2( const UTF8String &str );
      UTF8String ConvertToUTF8( const UCS2String &str );

    Las conversiones son sencillas, google debería ayudar aquí …

    Que es. Uso UTF8String donde la memoria es preciosa y para todos los UTF-8 I/O. el Uso de UCS2String donde la cadena debe ser analizado y/o manipulado. Usted puede convertir entre los dos representaciones en cualquier momento.

    Alternativas & Mejoras

    • conversiones de & byte codificaciones de caracteres (por ejemplo, ISO-8859-1) puede ser realizado con ayuda de la llanura de las tablas de traducción, por ejemplo, const wchar_t tt_iso88951[256] = {0,1,2,...}; y el código adecuado para la conversión a & desde UCS2.

    • si UCS-2 no es suficiente, de cambiar a UCS-4 (typedef std::basic_string<uint32_t> UCS2String)

    De la UCI o de otros unicode bibliotecas?

    Para un material avanzado.

    • Dang, no es bueno saber que los nativos soporte Unicode no está allí.
    • Tengo curiosidad por saber si has probado Glib::ustring y si es así, ¿cuáles son sus pensamientos?
    • Sé Simplista, pero no la usé nunca, y probablemente yo nunca los uso, porque es bastante limitado a un lugar inespecíficos plataforma de destino (unixoid sistemas…). Su puerto de windows se basa en el exterior win2unix-capa, y allí en mi humilde opinión no es OSX-compatibilidad de la capa en todos. Todo esto está indicando claramente en una dirección equivocada, al menos para mi código (en este arco de nivel…) 😉 Así que, Glib no es una opción
    • Creo que los puntos 2 y 3 están gritando para NO usar std::string utf8. SI usted todavía desea guardar en la memoria, entonces la subclase std::string para que usted obtenga al menos afirma y advertencias cuando usar substr, concat y longitud, y básicamente cualquier contenido perturbador de la cadena de operación funcionalidad. Personalmente aconsejo utilizar wstrings cadenas unicode, sin importar si usted coloca en utf8, 16 o 32, o ucs-2. Usted tendrá un tiempo mucho más fácil hacer IO con aquellos. Incluso componentes de interfaz de usuario hoy en día tratar adecuadamente con cadenas unicode, por lo que el downconversion sólo debería ser necesario cuando se trata con los componentes anteriores.
    • Tal vez… Pero subclases std::string resultados en tan sólo otro punto de vista sobre el problema, que es sólo otro tipo equivocado de «std::string», como std::string, de por sí ya es. Un solución integral contendría de un std::string que difiere entre memoria problemas de diseño y el carácter de la secuencia de temas. Así que, para empezar, por ejemplo, un std::string debe disponer de un método size() y un método nchars().
    • Por CIERTO: Incluso C++11x, C++14x ni las futuras normas, ni nadie lo hizo todavía la atención acerca de ese problema. Así, I18N en C++, es todavía una cosa cuando las soluciones son aún espera…
    • Ah, y @StarShine: leer la respuesta completa por favor. No es tan fácil como usted puede pensar.
    • Ah, tal vez se me perdió. ¿Cómo funciona su «UTF8String» typedef lograr una solución integral que difiere entre memoria problemas de diseño y secuencia de caracteres problemas? Es una herramienta de refactorización en el mejor, pero no es una solución. En primer lugar, la buena suerte obligando a nchars() en el estándar. En segundo lugar, ¿qué tan seguro puede ser realmente que la 3ª parte de libs no cortar su utf8 secuencias? Finalmente, utf8 es más difícil de analizar y depurar. Si utiliza wstring y ucs2 o adecuada utf16 desde el inicio, el depurador se mostrará la correcta cadena China, sin la necesidad de un rompecabezas se reúnen a partir de códigos de byte.
    • Un UTF8String typedef no es una solución integral. Es sólo una solución pragmática que funciona (en la mayoría de los casos, la mayoría del tiempo). En mi humilde opinión, es el momento para que los estándares de C++ para ofrecer una mejor solución. Los conceptos básicos (Unicode y sus diferentes esquemas de codificación, como UTF8 y UCS-2, están aquí y aquí para quedarse), así que es el momento adecuado ahora 😉
    • Por favor, tenga en cuenta también, que mi solución va a tener los mismos problemas como UCS-2, por ejemplo, cuando se trabaja con el chino cadenas! Así que, esto es realmente sólo un pragmatical cosa, no hay solución integral.
    • Buscar, reemplazar, y así sucesivamente funciona bien en UTF-8 cuerdas (una parte de la secuencia de bytes que representa a un personaje nunca puede ser mal interpretado como otro personaje). De hecho, UTF-16 y UTF-32 no hacer esto más fácil a todos: las tres codificaciones son codificaciones multibyte en la práctica, debido a que un usuario percibe carácter (grafema clúster) puede ser cualquier número de puntos de codificación unicode de largo! La solución pragmática es el uso de UTF-8 para todo, y convertir a UTF-16 sólo cuando se trabaja con la API de Windows.
    • ¿Por qué crees que la pragmatical solución sería utilizar UTF-8 para todo? De un solo Byte Search & Reemplace el código no puede hacer mucho daño en UTF-8 secuencias de bytes, pero no va a resolver los problemas reales, ya sea 😛 Usando la codificación UTF-8 para «todo» es el camino equivocado para nadie… el Uso de UTF-8 para el almacenamiento & transferencia está bien, pero usando para el procesamiento de cadenas de caracteres se traducirá en un crecimiento exponencial de código necesario para manejar todos los casos & combinaciones. Tal vez. Pero tal vez todo basada en el personaje de operaciones puede ser reescrito para trabajar en grafemas? Probablemente no, ¿verdad? Así que…
    • reemplazar y así sucesivamente» NO acaba de funcionar bien en cadenas de UTF-8, por desgracia, es mucho más complicado, véase, por ejemplo, utf8everywhere.org/#myth.strlen – y, por supuesto, UTF-16 y UTF-32 no hacer esto más fácil. Así?
    • Buscar y reemplazar funciona igual de bien con UTF-8 como codificación UTF-32. Es precisamente porque adecuada que soporte Unicode de procesamiento de texto que necesita tratar con multi-punto de código ‘personajes’ de todos modos, que el uso de una variable de codificación de longitud como UTF-8 no hacer el procesamiento de cadenas más complicada. Tan sólo utilizar UTF-8 en todas partes. C Normal de las funciones de cadena funcionará bien en UTF-8 (y corresponden a comparaciones ordinales en la cadena Unicode), y si necesitas algo más de conocimiento del lenguaje, tendrás que llamar a un Unicode biblioteca de todos modos, UTF-16/32 no lo puede salvar de eso.
    • Hasta este impresionante supervisión en el idioma que se rectifique, echa un vistazo Glib::ustring, una realidad inteligente envoltura alrededor de std::string de la glibmm proyecto, que se ajusta a la normal string con métodos adecuados de toma de conciencia de que el número de caracteres (no de codificación bytes/chars) en la cadena.
    • ¿Cómo std::string trabajar con UTF-8? Pensé que std::string utiliza char, que está a sólo 1 byte?

  4. 25
    1. Si quieres tener distintos caracteres almacenados en su cadena. wide depende de la implementación. Visual C++ por defecto de 16 bits, si recuerdo correctamente, mientras que el GCC valores predeterminados en función del destino. Es de 32 bits de largo aquí. Por favor nota wchar_t (ancho tipo de caracteres) no tiene nada que ver con unicode. Es simplemente garantiza que se puede almacenar todos los miembros de la mayor conjunto de caracteres que la aplicación soporta por sus lugares, y al menos tan largo como char. Usted puede tienda cadenas unicode fino en std::string el uso de la utf-8 codificación demasiado. Pero no entiendo el significado de puntos de código unicode. Así str.size() no le dará la cantidad de lógica de caracteres en una cadena, sino que simplemente la cantidad de char o wchar_t elementos almacenados en esa cadena/wstring. Por esa razón, el gtk/glib contenedor de C++ personas han desarrollado una Glib::ustring clase que puede manejar utf-8.

      Si su wchar_t es de 32 bits de largo, entonces usted puede utilizar utf-32 como una codificación unicode, y puede almacenar y manejar cadenas unicode usando un fijo (utf-32 es de longitud fija) de la codificación. Esto significa que su wstring del s.size() función luego devolver la cantidad correcta de wchar_t elementos y lógico caracteres.

    2. Sí, char es siempre al menos 8 bits de largo, lo que significa que puede almacenar todos los valores ASCII.
    3. Sí, todos los principales compiladores de apoyo.
    • Tengo curiosidad acerca de la #2. Pensé 7 bits sería técnicamente válido también? O es necesario ser capaz de almacenar cualquier cosa últimos 7-bit ASCII caracteres?
    • sí, jalf. c89 especifica mínima rangos para los tipos básicos en su documentación de límites.h (unsigned char, que es 0..255 min), y un puro sistema binario para los tipos enteros. sigue char, unsigned char y signed char tienen longitudes de bits mínima de 8. c++ hereda esas reglas.
    • «Esto significa que su wstring s.el tamaño de la función() devolverá la cantidad correcta de wchar_t elementos lógicos y de los personajes.» Esto no es del todo exacta, incluso para Unicode. Sería más exacto decir de punto de código de «lógica carácter», incluso en UTF-32 un determinado carácter puede estar compuesto de varios puntos de codificación.
    • Están ustedes en esencia diciendo que C++ no tiene soporte nativo para el conjunto de caracteres Unicode?
    • «Pero no entienden el significado de puntos de código unicode.» En windows, tampoco std::wstring.
    • Que depende de cómo se defina «el soporte nativo». Puede almacenar secuencias de caracteres Unicode? Absolutamente. Proporciona ningún estándar de la clase que pueden operar en estas secuencias en términos de número de caracteres que se muestran en ella, en lugar de sólo ingenuamente la indización/encontrar/etc por un número de bytes, lo que, posiblemente, rompiendo las secuencias de puntos de codificación y conseguir que las cosas terriblemente mal? No. Y eso es tremendo. Este es el año 2017. Sólo espero que, ya que estamos consiguiendo finalmente estándar de sistema de archivos y de red de apoyo, tal vez real cadenas Unicode son apenas visibles en algún lugar sobre el horizonte.
    • Soporte para almacenar codificados en Unicode puntos de codificación en bytes son apenas notables como «apoyo». Y, sí, estoy de acuerdo en que la ausencia de la norma Unicode apoyo en este idioma en el siglo 21 es de risa.
    • al menos tenemos std::codecvt<charNN_t, char> etc. debido a que C++11 para la conversión entre UTF-NN y UTF-8. Aunque, std::wstring_convert está en desuso desde C++17…

  5. 5

    Frecuentemente uso std::string para contener caracteres utf-8 sin ningún tipo de problemas. Yo sinceramente recomiendo hacer esto para interactuar con la API de que el uso de utf-8 como el nativo tipo de cadena así.

    Por ejemplo, puedo usar utf-8 cuando se trate de mi código con el intérprete de Tcl.

    La principal limitación es la longitud de la std::string, ya no es más el número de caracteres de la cadena.

    • Juan : ¿quiere usted decir que std::string puede contener todos los caracteres unicode, pero la longitud de la informe incorrectamente? Hay una razón por la que se informa de longitud incorrecta?
    • Cuando se utiliza la codificación utf-8, un carácter unicode puede estar compuesto de múltiples bytes. Esta es la razón por la codificación utf-8 es menor cuando se utiliza la mayoría de los caracteres del ascii estándar establecido. Usted necesidad de utilizar funciones especiales (o rollo de su propia) para medir el número de caracteres unicode.
    • (Específicos de Windows) la Mayoría de las funciones se espera que una cadena de texto utilizando bytes 2 bytes ASCII y Unicode, las versiones anteriores MBCS. Lo que significa que si usted está almacenando 8 bit unicode que se tendrán que convertir a unicode de 16 bits para llamar a una función estándar de windows (a menos que usted es sólo el uso de ASCII parte).
    • Como Greg y Joel (software) mención, es muy importante para entender cómo la codificación trabaja con la API de que usted está tratando. Cambiando constantemente de ida y vuelta entre los 8 y los 16 bits de codificación en un sistema windows puede no ser óptima.
    • No sólo será una std::string informe de la longitud de forma incorrecta, sino que también va a la salida de la incorrecto de la cadena. Si algunos caracteres Unicode está representado en UTF-8 como varios bytes, que std::string piensa como sus propios personajes, su normalmente std::string rutinas de manipulación probablemente la salida de varios caracteres extraños que resultan de la interpretación de los un carácter correcto.
    • Si quiero hacer el programa (en windows) que serán libremente utilizando diferentes símbolos Unicode, como el Japonés / Chino caracteres, letras polaco, Cirílico, etc., ¿qué debo usar? Se UTF-8 será suficiente?
    • Lo que @Mihai Danila dijo. Recomiendo fuertemente contra el uso de std::string para utf-8, especialmente cuando estamos haciendo frecuentes operaciones de cadena como la concatenación y la sub-cadena. Widestrings puede tomar un montón de lugar, pero si usted es serio acerca de los productos de software y datos en un entorno multilingüe y multicultural del mundo, el uso de std::string se está convirtiendo arcaico, y tratando de utilizar sólo las camadas del código en todo tipo de lugares extraños con las funciones que ‘correcto’ para la mayoría de las veces. He estado en el desarrollo del juego durante casi 10 años, en diferentes plataformas, así que sé de lo que estoy diciendo.
    • Sugiero cambiar la respuesta para indicar que las cadenas debe ser pensado sólo como contenedores de bytes, y, si los bytes son algunos de codificación Unicode (UTF-8, UTF-16, …), entonces usted debe utilizar librerías específicas que entender eso. La cadena estándar basado en la Api (longitud, substr, etc.) todos fallan miserablemente con caracteres multibyte. Si esta actualización se hace, me va a quitar mi downvote.
    • No parece haber ninguna buena opciones en el estándar de C++ para la cruz-plataforma, de uso internacional. Hace poco escribí un texto impulsado por la interfaz gráfica de usuario para un programa que con la costumbre de saltos de línea, etiquetas semánticas, caracteres internacionales… Después de investigar varios enfoques, elegí std::las cadenas de caracteres usando la codificación UTF-8 para almacenar los datos de texto, pero la escritura de una biblioteca de funciones para asignar entre los caracteres y bytes, para realizar común de las funciones de cadena, tales como la inserción de texto, extracción y búsqueda, y para realizar las conversiones a otros formatos para i/o. Yo vine aquí a ver si ahora hay una mejor manera, no lo parece.

  6. 3
    1. Cuando se desea almacenar ‘ancho’ caracteres (Unicode).
    2. Sí: 255 de ellos (salvo el 0).
    3. Sí.
    4. He aquí un artículo introductorio: http://www.joelonsoftware.com/articles/Unicode.html
    • std::string puede contener 0 bien (solo tienes que tener cuidado si se llama a la c_str() método)
    • Y, hablando estrictamente, un char no está garantizado a ser de 8 bits. 🙂 Tu enlace en el #4 es una lectura obligada, pero no creo que responda a la pregunta. Un carácter ancho es estrictamente nada que ver con unicode. Es simplemente un carácter más amplio. (Cuánto más ancho depende del sistema operativo, pero normalmente de 16 o 32 bits)
    • amplia != unicode! (especialmente en windows)
  7. 2

    Las aplicaciones que no están satisfechos con sólo 256 caracteres diferentes, tienen las opciones de uso de caracteres anchos (más de 8 bits) o una variable de la codificación de longitud (una codificación multibyte en C++ terminología) como UTF-8. Caracteres anchos generalmente requieren más espacio que una variable codificación de longitud, pero son más rápidos proceso. Multi-idioma de las aplicaciones que procesan grandes cantidades de texto suelen utilizar distintos personajes al procesar el texto, pero convertir a UTF-8 cuando el almacenamiento en disco.

    La única diferencia entre un string y un wstring es el tipo de datos de los caracteres de la tienda. Una cadena de tiendas de chars cuyo tamaño está garantizado para ser de al menos 8 bits, por lo que se pueden utilizar cadenas para el procesamiento por ejemplo, ASCII, ISO-8859-15, o texto UTF-8. La norma no dice nada sobre el conjunto de caracteres o de codificación.

    Prácticamente cada compilador utiliza un conjunto de caracteres cuyos primeros 128 caracteres se corresponden con los caracteres ASCII. Este es también el caso de los compiladores que utilizan la codificación UTF-8. La cosa importante a tener en cuenta al utilizar cadenas de caracteres en UTF-8 o alguna otra variable de la codificación de longitud, es que los índices y las longitudes se miden en bytes, no personajes.

    El tipo de datos de un wstring es wchar_t, cuyo tamaño no está definido en el estándar, excepto que tiene que ser al menos tan grande como un char, generalmente de 16 bits o de 32 bits. wstring puede ser utilizado para el procesamiento de texto en el definido por la implementación amplia de codificación de caracteres. Debido a que la codificación no está definido en la norma, no es sencillo convertir entre cuerdas y wstrings. Uno no puede asumir wstrings tener una longitud fija de codificación de cualquiera.

    Si usted no necesita el soporte multi-idioma, usted podría estar bien sólo con el uso regular de las cadenas. Por otro lado, si usted está escribiendo una aplicación gráfica, es a menudo el caso de que la API sólo admite caracteres anchos. Entonces usted probablemente querrá utilizar el mismo ancho de caracteres al procesar el texto. Tenga en cuenta que la codificación UTF-16 es una variable codificación de longitud, lo que significa que usted no puede asumir length() para devolver el número de caracteres. Si la API utiliza una longitud fija de codificación, tales como UCS-2, el procesamiento se convierte en fácil. Conversión entre distintos personajes y UTF-8 es difícil hacerlo en un portátil, pero, de nuevo, la interfaz de usuario de la API probablemente soporta la conversión.

    • Así que, parafraseando el primer párrafo de la Aplicación: la necesidad de más de 256 caracteres necesidad de utilizar un multibyte-codificación o una maybe_multibyte-codificación.
    • Generalmente, 16 y 32 bits codificaciones como UCS-2 y UCS-4, no se llama codificaciones multibyte, aunque. El estándar de C++ distingue entre codificaciones multibyte y ancho de los caracteres. Una amplia representación de caracteres utiliza un número fijo (generalmente más de 8) bits por carácter. Las codificaciones que el uso de un solo byte para codificar los caracteres más comunes, y varios bytes para codificar el resto del conjunto de caracteres, se llama codificaciones multibyte.
    • Lo siento, descuidado comentario. Debería haber dicho de longitud variable codificación. UTF-16 es una variable de la longitud de la codificación, como UTF-8. Pretender que no es un mal idea.
    • Ese es un buen punto. No hay ninguna razón por qué wstrings no podía ser utilizado para almacenar UTF-16 (en lugar de UCS-2), pero, a continuación, la comodidad de una longitud fija de codificación se pierde.
  8. 1
    1. cuando desee utilizar cadenas Unicode y no sólo ascii, útil para la internacionalización
    2. sí, pero no juega bien con 0
    3. no es consciente de que cualquiera que no
    4. carácter ancho es el compilador de forma específica de la manipulación de la representación de longitud fija de un carácter unicode, para MSVC es de 2 caracteres de byte, para gcc entiendo que es de 4 bytes. y un +1 para http://www.joelonsoftware.com/articles/Unicode.html
    • 2. Un std::string puede contener un carácter NULO bien. También puede contener utf-8 y amplia a los personajes.
    • Que me pone en confusión de nuevo. Si std::string puede mantener los caracteres unicode, lo que es especial con std::wstring?
    • std::string puede contener UTF-8 caracteres unicode. Hay un número de unicode normas dirigidas a los diferentes caracteres anchos. UTf8 es de 8 bits de ancho. También hay UTF-16 y UTF-32 en 16 y 32 bits de ancho respectivamente
    • Con un std::wstring. Cada uno de los caracteres unicode puede ser uno wchar_t cuando se utiliza la longitud fija de codificaciones. Por ejemplo, si usted elige utilizar el joel en el enfoque de software como Greg enlaces. Entonces la longitud de la wstring es exactamente el número de caracteres unicode en la cadena. Pero ocupa más espacio
    • Yo no he dicho que no podía tener un 0 ‘\0’, y lo que me refería con no jugar bien es que algunos métodos pueden no dar el resultado esperado que contiene todos los datos de la wstring. Tan dura en la parte baja de los votos.
    • No quise ofender. Pero yo no estaba de acuerdo con sus respuestas a las 1 y 2. Puedo ver de Joel, el argumento de por qué es posible que desee utilizar wchar_t cuando se trabaja en un sistema windows. Sin embargo, una regular char funciona igual de bien para i18n.

  9. 0

    Hay algunas muy buenas respuestas aquí, pero creo que hay un par de cosas que me pueden agregar con respecto a Windows y Visual Studio. Tis es basado en mi experiencia con VS2015. En Linux, básicamente, la respuesta es utilizar la codificación UTF-8 std::string en todas partes. En Windows/VS se vuelve más complejo. Aquí es por qué. Windows espera que las cadenas se almacenan utilizando chars para ser codificados utilizando la configuración regional de la página de códigos. Este es casi siempre el conjunto de caracteres ASCII seguido por 128 caracteres especiales dependiendo de su ubicación. Permítanme estado que no sólo cuando se utiliza la API de Windows, hay otros tres de los principales lugares donde estas cadenas de interactuar con el estándar de C++. Estos son los literales de cadena, salida a std::cout utilizando << y pasa un nombre de archivo para std::fstream.

    Voy a estar hasta el frente aquí que yo soy un programador, no un especialista en lenguaje. Agradezco que USC2 y UTF-16 no son los mismos, pero para mis propósitos están lo suficientemente cerca para ser intercambiables y yo los uso como tal aquí. No estoy realmente seguro que Windows utiliza, pero generalmente no hay necesidad de saber. He dicho UCS2 en esta respuesta, así que lo siento de antemano si ofendí a alguien con mi ignorancia de este tema, y estoy feliz de cambiar si tengo mal las cosas.

    Literales de cadena

    Si usted entra en los literales de cadena que contienen sólo los caracteres que puede ser representado por su página de códigos VS almacena en el archivo con 1 byte por carácter de codificación basado en su página de códigos. Tenga en cuenta que si cambia su página de códigos o dar origen a otro desarrollador utilizando un código diferente de la página, a continuación, creo (pero no las he probado) que el personaje va a terminar diferente. Si se ejecuta el código en un equipo utilizando un código diferente de la página, a continuación, no estoy seguro de si el personaje va a cambiar demasiado.

    Si entras en las literales de cadena que no puede ser representado por su página de códigos que VS le pedirá que guarde el archivo como Unicode. El archivo, a continuación, ser codificado como UTF-8. Esto significa que No todos los caracteres ASCII (incluyendo los que están en su página de códigos) será representado por 2 o más bytes. Esto significa que si usted da su origen a alguien de la fuente tendrá el mismo aspecto. Sin embargo, antes de pasar la fuente para el compilador, VS convierte el texto codificado UTF-8 para el código de la página de texto codificados y los caracteres que faltan de la página de código se sustituyen con ?.

    La única manera de garantizar representar correctamente una cadena Unicode literal en el VS es preceder el literal de cadena, con un L lo que es una gran cadena literal. En este caso VS convertirá el texto codificado UTF-8 desde el archivo en UCS2. Entonces usted necesita para pasar este literal de cadena en un std::wstring constructor o usted necesita para convertir a utf-8 y lo puso en un std::string. O si lo desea, puede utilizar las funciones de API de Windows para codificar mediante su página de código para ponerlo en un std::string, pero entonces puede que así no han utilizado una amplia literal de cadena.

    std::cout

    Cuando la salida de la consola mediante el uso de << sólo puede utilizar std::string, no std::wstring y el texto debe ser codificados utilizando la configuración regional de la página de códigos. Si usted tiene un std::wstring, a continuación, debe convertirlo usando una de las funciones de API de Windows y todos los caracteres que no están en su página de códigos que se sustituye por ? (tal vez usted puede cambiar el carácter, no recuerdo).

    std::fstream nombres de archivo

    Sistema operativo Windows utiliza UCS2/UTF-16 para sus nombres de archivo de modo que cualquiera que sea tu página de códigos, usted puede tener archivos con cualquier carácter Unicode. Pero esto significa que para acceder o crear archivos con caracteres que no están en su página de códigos debe utilizar std::wstring. No hay otra manera. Este es un Microsoft extensión específica para std::fstream así que probablemente no se compilará en otros sistemas. Si usted usa std::string, a continuación, sólo se puede utilizar nombres de archivo que sólo incluyen a los personajes en su página de códigos.

    Sus opciones

    Si usted está trabajando en Linux, entonces usted probablemente no llegar a este punto. Sólo el uso de UTF-8 std::string en todas partes.

    Si usted está trabajando en Windows, simplemente uso UCS2 std::wstring en todas partes. Algunos puristas puede decir usar UTF8, a continuación, convertir cuando sea necesario, pero ¿por qué molestarse con la molestia.

    Si son multiplataforma, es un lío para ser franco. Si intenta utilizar la codificación UTF-8 en todas partes en Windows, entonces usted necesita ser muy cuidadoso con su literales de cadena y la salida a la consola. Usted puede fácilmente dañar sus cadenas. Si utiliza std::wstring en todas partes en Linux, a continuación, usted no puede tener acceso a la versión amplia de std::fstream, por lo que tiene que hacer la conversión, pero no hay riesgo de corrupción. Así que personalmente creo que esta es una mejor opción. Muchos no estarían de acuerdo, pero no estoy sola, que es la ruta tomada por los wxWidgets por ejemplo.

    Otra opción podría ser typedef unicodestring como std::string en Linux y std::wstring en Windows, y tiene una macro que se llama UNI (), el cual prefijos L en Windows y nada en Linux, a continuación, el código

    #include <fstream>
    #include <string>
    #include <iostream>
    #include <Windows.h>
    #ifdef _WIN32
    typedef std::wstring unicodestring;
    #define UNI(text) L ## text
    std::string formatForConsole(const unicodestring &str)
    {
    std::string result;
    //Call WideCharToMultiByte to do the conversion
    return result;
    }
    #else
    typedef std::string unicodestring;
    #define UNI(text) text
    std::string formatForConsole(const unicodestring &str)
    {
    return str;
    }
    #endif
    int main()
    {
    unicodestring fileName(UNI("fileName"));
    std::ofstream fout;
    fout.open(fileName);
    std::cout << formatForConsole(fileName) << std::endl;
    return 0;
    }

    estaría bien en cualquier plataforma, creo.

    Respuestas

    Así que para responder A sus preguntas

    1) Si usted está de programación para Windows, a continuación, todo el tiempo, si la plataforma de la cruz, a continuación, tal vez todo el tiempo, a menos que usted quiere tratar con posibles problemas de corrupción en Windows o escribir algún código específico de la plataforma #ifdefs para trabajar en torno a las diferencias, si sólo usa Linux, nunca.

    2)Sí. Además en Linux se puede utilizar para todas las Unicode demasiado. En Windows solo se puede utilizar para todos unicode si usted decide codificar manualmente con UTF-8. Pero la API de Windows y el estándar de C++, las clases se espera que la std::string a ser codificados utilizando la configuración regional de la página de códigos. Esto incluye todos los ASCII además de otros 128 caracteres que cambian según la página de códigos que su equipo está configurado para su uso.

    3)yo creo que sí, pero si no, entonces es sólo una simple typedef de un ‘std::basic_string’ mediante wchar_t en lugar de char

    4)Un carácter ancho es un tipo de carácter que es más grande que el 1 byte estándar char tipo. En Windows es de 2 bytes, en Linux es de 4 bytes.

    • Con respecto a la «sin Embargo, antes de pasar la fuente para el compilador, VS convierte el texto codificado UTF-8 para el código de la página de texto codificados y los caracteres que faltan de la página de código se sustituyen con ?.» -> no creo que esto es cierto cuando el compilador utiliza la codificación UTF-8 (uso /utf-8).
    • Yo no era consciente de esto como una opción. Desde este enlace docs.microsoft.com/en-us/cpp/build/reference/… parece que no hay casilla para seleccionar en las propiedades del proyecto, se debe agregar como una opción de línea de comandos. Buen lugar!
  10. 0

    Una buena pregunta!
    Creo que CODIFICACIÓN de los DATOS, (a veces un CHARSET también implicados) es un MEMORIA EXPRESIÓN MECANISMO para guardar datos en un archivo o transferencia de datos a través de una red, así que la respuesta a esta pregunta como:

    1. Cuando debo usar std::wstring más de std::string?

    Si la plataforma de programación o API función es de un solo byte uno, y queremos procesar o analizar algunos datos Unicode, e.g leer desde Windows’.Archivo REG o de la red 2-secuencia de bytes, debemos declarar std::wstring variable fácilmente el proceso de ellos. por ejemplo: wstring ws=L»中国a»(6 octetos de memoria: 0x4E2D 0x56FD 0x0061), podemos utilizar ws[0] para obtener el carácter ‘中’ y ws[1] para obtener el carácter ‘国’ y ws[2] para obtener la letra ‘a’, etc.

    2. Puede std::string contener todo el conjunto de caracteres ASCII, incluyendo los caracteres especiales?

    Sí. Pero aviso: American ASCII, significa que cada 0x00~0xFF octeto representa un carácter, incluyendo texto imprimible como «123abc&*_&» y dijo uno en especial, principalmente de impresión como un ‘.’ evitar confundir a los editores o terminales. Y algunos otros países de extender su propia «ASCII» charset, por ejemplo, el Chino, el uso de 2 octetos a pie por uno de los personajes.

    3.Es std::wstring apoyado por todos los compiladores de C++?

    Tal vez, o en su mayoría. Que he utilizado: VC++6 y GCC 3.3, SÍ

    4. ¿Qué es exactamente un «gran personaje»?

    una amplia carácter mayormente indica el uso de 2 octetos o 4 octetos para contener todos los países de caracteres. 2 octeto UCS2 es una muestra representativa, y más por ejemplo, en inglés ‘a’, su memoria es de 2 octeto de 0x0061(vs en ASCII ‘la memoria es de 1 octeto 0x61)

  11. -5

    Cuándo NO debe usar distintos caracteres?

    Cuando estás escribiendo código antes del año 1990.

    Obviamente, estoy siendo flip, pero en realidad, es el siglo 21 ahora. 127 caracteres desde hace mucho han dejado de ser suficiente. Sí, usted puede usar UTF8, pero ¿por qué molestarse con los dolores de cabeza?

    • No sé qué dolor de cabeza no UTF-8 cree que es mayor que la de Widechars (UTF-16). en UTF-16, también tiene varios caracteres los caracteres.
    • El problema es que si usted está en cualquier lugar, pero país de habla inglesa se DEBE usar wchar_t. Por no mencionar que algunos alfabetos tienen más caracteres de los que cabe en un byte. Estábamos allí, en DOS. La página de códigos de la esquizofrenia, no, gracias, no hay más..
    • El problema con wchar_t es que su tamaño y el sentido específico de un SO. Sólo intercambia los problemas viejos con los nuevos. Mientras que un char es un char independientemente del sistema operativo (en plataformas similares, al menos). Así que podría usar UTF-8, empacar todo en las secuencias de chars, y se lamentan de cómo C++ nos deja completamente por nuestra cuenta sin ningún tipo de métodos estándar para la medición, indexación, búsqueda, etc dentro de dichas secuencias.
    • Lo que usted describe es el más pequeño de los problemas en caso de que el código en C++. Carácter ancho wchat_t es fundamental escriba en C++, pero no en C, pero su representación binaria no es de la plataforma se define como la describe, es tiempo de ejecución. Así personaje puede ser de 1 byte o 2 bytes de longitud (al menos) en función de lo real de la cadena se almacena. Unicode UTF-16 son de tamaño fijo de caracteres. La cosa es que wchar_t es el tipo que sea compatible para ciertos plataforma en el nivel de sistema de archivos de nombres (incluyendo windows), mientras que otras plataformas uso de caracteres multibyte
    • Parece que tienes es completamente al revés. wchar_t es un ancho fijo tipo de datos, por lo que una matriz de 10 wchar_t ocupará siempre sizeof(wchar_t) * 10 plataforma de bytes. Y UTF-16 es un ancho variable de codificación en la que los personajes podrán ser de 1 o 2 de 16 bits puntos de codificación (y s/16/8/g para UTF-8).
    • Lo siento, eso es malo, al menos para wchar_t en Windows. En Windows, un wchar_t es una codificación UTF-16. Prueba Simple: wchar_t *test = L»𠀀»; // Código de punto U+20000 En el depurador, verás una cadena de dos valores: 0xD840, y 0xDC00, que es la codificación UTF-16 del personaje.
    • guardó utf16, de modo que usted lo consigue. es una compilación de dependientes del tipo primitivo que no emitidos o limitar lo que intenta asignar a la misma. Cómo API y el compilador podría tratar ist es indefinido, en general no es la misma representación que los caracteres unicode.wchar_t como se define por la api de windows es 16 bits por carácter. así que lo que tienes es un sustituto de dos caracteres con códigos de 0X00DC y 0x40D8. pero el código que la trate como unicode matriz, actuaría correctamente, sólo sería muy difícil determinar si es de 2 caracteres o uno. En linux wchar_t es de 32 bits, el código no va a causar un problema
    • wchar_t representación de cadena en windows sería codificar los caracteres mayor que FFFF como aspecial par suplente, otros solamente uno wchar_t elemento. De modo que la representación no será compatible con la representación creada por el compilador de gnu (donde todos los caracteres menos de FFFF tendrán ninguna palabra en frente de ellos). Lo que se almacena en wchar_t es determinado por el programador y el compilador, no por medio de algún acuerdo

Dejar respuesta

Please enter your comment!
Please enter your name here