2008-12-01 28 views
44

¿Cuál es la codificación estándar del código fuente de C++? ¿El estándar de C++ incluso dice algo sobre esto? ¿Puedo escribir fuente C++ en Unicode?Uso de Unicode en el código fuente de C++

Por ejemplo, ¿puedo utilizar caracteres no ASCII como caracteres chinos en los comentarios? Si es así, ¿está permitido Unicode completo o solo un subconjunto de Unicode? (por ejemplo, esa primera página de 16 bits o como se llame.)

Además, ¿puedo usar Unicode para cadenas? Por ejemplo:

Wstring str=L"Strange chars: â Țđ ě €€"; 
+0

* RE: "como se llame": * [De Wikipedia] (https://en.wikipedia.org/wiki/Plane_%28Unicode%29#Basic_Multilingual_Plane): El primer avión, ** plano 0 **, ** Plano básico multilingüe (BMP) ** contiene caracteres para casi todos los idiomas modernos y una gran cantidad de símbolos. Un objetivo principal para el BMP es apoyar la unificación de conjuntos de caracteres anteriores, así como los caracteres para la escritura. La mayoría de los puntos de código asignados en el BMP se utilizan para codificar caracteres ** chinos **, ** japoneses ** y ** coreanos (CJK) **. – DavidRR

Respuesta

33

La codificación en C++ es bastante complicada. Aquí está mi entendimiento de eso.

Cada implementación tiene que admitir caracteres del conjunto de caracteres de origen básico . Estos incluyen caracteres comunes enumerados en §2.2/1 (§2.3/1 en C++ 11). Estos personajes deben caber todos en uno char. Además, las implementaciones tienen que admitir una manera de nombrar otros caracteres usando un método llamado universal-character-names y se parecen a \uffff o \Uffffffff y se pueden usar para referirse a caracteres Unicode. Un subconjunto de ellos se puede utilizar en identificadores (enumerados en el Anexo E).

Esto es muy bueno, pero la asignación de los caracteres en el archivo, a los caracteres de origen (utilizados en tiempo de compilación) es la implementación definida. Esto constituye la codificación utilizada. Aquí es lo que dice literalmente (versión C++ 98):

caracteres del archivo de origen físico son mapeados, en una forma definida por la implementación, al carácter fuente básica conjunto (introduciendo caracteres de nueva línea para indicadores de fin de línea) si es necesario . Las secuencias de Trigraph (2.3) se reemplazan por las representaciones de un solo carácter internas . Cualquier archivo de origen cuyo carácter no se encuentre en la fuente básica , el juego de caracteres (2.2) se sustituirá por el nombre-carácter-universal que des- ignata ese carácter.(Un implementación puede utilizar cualquier codificación interna, siempre que un carácter extendido real encontrado en el archivo fuente, y el mismo extendida carácter expresado en el archivo fuente como caracteres-nombre universal (es decir usando el \ uXXXX notación), se manejado de manera equivalente.)

Para gcc, se puede cambiar mediante la opción -finput-charset=charset. Además, puede cambiar el carácter de ejecución utilizado para reestablecer valores en tiempo de ejecución. La opción adecuada para esto es -fexec-charset=charset para char (por defecto es utf-8) y -fwide-exec-charset=charset (que por defecto es utf-16 o utf-32 según el tamaño de wchar_t).

9

El estándar C++ no dice nada acerca de la codificación del archivo de código fuente, hasta donde yo sé.

La codificación habitual es (o solía ser) ASCII de 7 bits: algunos compiladores (Borland's, por ejemplo) se resistirían a los caracteres ASCII que usaban el bit alto. No hay ninguna razón técnica para que los caracteres Unicode no se puedan usar, si su compilador y editor los aceptan, la mayoría de las herramientas modernas basadas en Linux y muchos de los mejores editores basados ​​en Windows manejan la codificación UTF-8 sin problemas, aunque yo No estoy seguro de que el compilador de Microsoft lo haga.

EDIT: Parece que los compiladores de Microsoft aceptarán archivos Unicode codificado, pero a veces se producen errores en ASCII de 8 bits también:

warning C4819: The file contains a character that cannot be represented 
in the current code page (932). Save the file in Unicode format to prevent 
data loss. 
+0

Es algo así como No creo que explícitamente evite o permita unicode, pero este es el conjunto de caracteres mínimo permitido: http://www.csci.csusb.edu/dick/c++std/cd2/lex.html#lex.charset –

+0

Desde C++ Builder2007, el compilador Borland/Codegear ha admitido archivos fuente Unicode: es decir, literales de cadenas Unicode, comentarios unicode. el IDe ha tenido problemas con ellos, ¡pero el compilador está contento! – Roddy

+0

Lo que mencioné de Borland fue hace aproximadamente veinte años (la última vez que intenté poner un carácter ASCII alto en un archivo de código fuente). :-) No he usado un compilador de Borland en unos diez años. –

3

Para la codificación de las cadenas Creo que están destinados a utilizar el \ u notación, por ejemplo:

std::wstring str = L"\u20AC"; // Euro character 
0

yo sepa no es estandarizado como se puede poner cualquier tipo de caracteres en las cadenas de ancho. Solo tiene que comprobar que su compilador está configurado en código fuente Unicode para que funcione correctamente.

2

También vale la pena señalar que los caracteres anchos en C++ no son realmente cadenas Unicode como tales. Son solo cadenas de caracteres más grandes, generalmente 16, pero a veces 32 bits. Sin embargo, esto es una implementación definida. IIRC puede tener un wchar_t de 8 bits. No tiene ninguna garantía real en cuanto a la codificación en ellos, por lo que si está tratando de hacer algo como procesamiento de texto, probablemente querrá un typedef al máximo tipo de entero adecuado para su entidad Unicode.

C++ 1x tiene apoyo adicional Unicode en forma de UTF-8 literales de codificación de cadena (u8"text"), y UTF-16 y 32 UTF-tipos de datos (char16_t y char32_t IIRC), así como las constantes de cadena correspondientes (u"text" y U"text"). Sin embargo, la codificación en caracteres especificados sin \uxxxx o \Uxxxxxxxx constantes todavía está definida por la implementación (y no hay soporte de codificación para tipos de cadena complejos fuera de los literales)

+0

¿No es la letra minúscula 'u' solo para los personajes? – Tomasito665

6

Hay dos cuestiones en juego aquí. El primero es qué caracteres están permitidos en el código C++ (y comentarios), como nombres de variables. El segundo es qué caracteres se permiten en cadenas y literales de cadena.

Como se indicó, los compiladores de C++ deben contener un conjunto de caracteres ASCII muy restringido para los caracteres permitidos en el código y los comentarios. En la práctica, este juego de caracteres no funcionó muy bien con algunos juegos de caracteres europeos (y especialmente con algunos teclados europeos que no tenían algunos caracteres, como corchetes, disponibles), por lo que el concepto de dígrafos y trigrafos era introducido. Muchos compiladores aceptan más que este conjunto de caracteres en este momento, pero no hay ninguna garantía.

En cuanto a cadenas y literales de cadenas, C++ tiene el concepto de un carácter ancho y una cadena de caracteres anchos. Sin embargo, la codificación para ese juego de caracteres no está definida. En la práctica, casi siempre es Unicode, pero no creo que haya ninguna garantía aquí. Los literales de cadena de caracteres anchos parecen L "literal de cadena", y estos se pueden asignar a std :: wstring.


C++ 11 Añadido soporte explícito para cadenas Unicode y literales de cadena, codificado como UTF-8, UTF-16 big endian, UTF-16 poco endian, UTF-32 big endian y UTF-32 Little Endian .

9

Además de la publicación de litb, MSVC++ también admite Unicode. Entiendo que obtiene la codificación Unicode de la lista de materiales. Definitivamente es compatible con código como int (*♫)(); o const std::set<int> ∅; Si usted está realmente en código obfuscuation:

typedef void ‼; // Also known as \u203C 
class ooɟ { 
    operator ‼() {} 
}; 
+1

Esto puede ser útil para escribir, por ejemplo, software matemático donde el código fuente se puede alinear con el material fuente. Puede hacer esto en Java, que acepta el código fuente UTF-8. Sin embargo, para C++ (y C) puede haber problemas en cómo los tokens que no son ASCII se transforman en nombres de símbolos, que tiene que ser compatible con el resto del sistema operativo, no solo una característica del compilador. Para C++ esto podría ser subsumido por el cambio de nombre. –

2

En este contexto, si se obtiene MSVC++ advertencia C4819, sólo cambia el archivo de origen de codificación a "UTF-8 con Bom" .

GCC 4.1 no es compatible con esto, pero GCC 4.4 lo hace, y la última versión de Qt usa GCC 4.4, por lo tanto, utilice "UTF-8 con Bom" como código de fuente de codificación.

Cuestiones relacionadas