2011-02-03 19 views
6

En Visual Studio 2005 en Windows de 32 bits, ¿por qué mi consola no muestra caracteres de 128 a 255?Mostrar caracteres ASCII extendidos

por ejemplo:

cout << "¿" << endl; //inverted question mark 

Salida:

┐ 
Press any key to continue . . . 
+0

Parece que funciona bien, tus conjuntos de caracteres simplemente no coinciden. Bienvenido al mundo de los conjuntos heredados, porque parece que la consola de Windows todavía (!!) no hace Unicode. –

+0

¿Viene bajo Unicode? – user3234

+2

La consola de Windows sí hace Unicode. Para ser precisos, 'WriteConsoleW' sí. 'WriteConsoleA' obviamente no. – MSalters

Respuesta

12

Una ventana de consola de Windows es Unicode puro. Su buffer almacena texto como UCS-2 Unicode (16 bits por carácter, esencialmente como Unicode original, una restricción al Basic Multilingual Plane del moderno Unicode de 21 bits). Entonces una ventana de consola puede presentar casi todo tipo de texto.

Sin embargo, para byte único por carácter (y posiblemente también para algunas codificaciones de longitud variable) i/o Windows se traduce automáticamente a/desde la página de códigos activa de la ventana de consola. Si la ventana de la consola es una instancia [cmd.exe], entonces puede inspeccionarlo a través del comando chcp, abreviatura de cambiar la página de códigos. De esta manera:

 
C:\test> chcp 
Active code page: 850 

C:\test> _ 

página de códigos 850 es una codificación basado en el original juego de caracteres IBM PC Inglés 437. 850 es el valor predeterminado para las ventanas de consola en al menos PC de Noruega (aunque los noruegos conocedores puede cambiar eso a 865). Sin embargo, ninguna de ellas es una página de códigos que deba usar.

El original IBM PC página de códigos (codificación de caracteres) es conocido como OEM, que es un acrónimo de sentido, fabricante de equipos originales. Tenía lindos personajes de dibujo de línea adecuados para la pantalla del modo de texto de la PC original. En general, OEM significa la página de códigos predeterminada para las ventanas de la consola, donde la página de códigos 437 es solo la original: se puede configurar, p. por ventana a través de chcp.

Cuando Microsoft creó Windows de 16 bits, eligieron otra codificación conocida en Windows como ANSI. La original era una extensión de ISO Latin-1 que durante mucho tiempo fue la predeterminada en Internet (sin embargo, no está claro cuál fue primero: Microsoft participó en la estandarización). Este ANSI original ahora se conoce como Windows ANSI Western.

ANSI es la página de códigos utilizada para no-Unicode por casi todo el resto de Windows. Las ventanas de la consola usan OEM. El Bloc de notas, otros editores, etc., usan ANSI.

Luego, cuando Microsoft creó Windows 32-bit, adoptaron una extensión de 16 bits de Latin-1 conocida como Unicode. Microsoft fue un miembro fundador original del Consorcio Unicode. Y la API básica, incluidas las ventanas de consola, el sistema de archivos, etc., se reescribió para usar Unicode. Para compatibilidad con versiones anteriores, hay una capa de traducción que traduce entre OEM y Unicode para ventanas de consola, y entre ANSI y Unicode para otras funcionalidades. Por ejemplo, MessageBoxA es un contenedor ANSI para MessageBoxW basado en Unicode.

El resultado práctico de eso es que en Windows su código fuente de C++ normalmente está codificado con ANSI, mientras que las ventanas de la consola asumen OEM. Que v.g. hace

cout << "I like Norwegian blåbærsyltetøy!" << endl; 

produce pure gobbledegook & hellip; Puede usar las API de la ventana de la consola basada en Unicode para enviar Unicode directamente a una ventana de la consola, evitando la traducción, pero eso es incómodo.

Tenga en cuenta que el uso de wcout en lugar de cout no ayuda: por diseño wcout simplemente se traduce por debajo de las cadenas de caracteres de ancho a estrecho conjunto de caracteres del programa, descartando la información en el camino. Puede ser difícil de creer que la biblioteca estándar de C++ ofrezca una gran parte de la funcionalidad muy compleja que no tiene sentido (ya que esas conversiones podrían haber sido admitidas por cout). Pero así es, simplemente sin sentido. Posiblemente fue un compromiso de tipo político, pero de todos modos, wcout hace no ayuda, aunque si era significativo de alguna manera, entonces "lógicamente" debería ayudar con esto.

Entonces, ¿cómo consigue un programador novato noruego, p. "blåbærsyltetøy" presentado?

Bueno, simplemente cambiando la página de códigos activos a ANSI. Dado que en la mayoría de los PC de los países occidentales es la página de códigos ANSI 1252, que puede hacer que para una instancia determinada por el intérprete de comandos

 
C:\test> chcp 1252 
Active code page: 1252 

C:\test> _ 

programas de DOS Ahora antiguos como por ejemplo, [edit.com] (¡todavía presente en Windows XP!) producirá un poco de palabrería, porque los caracteres del dibujo de líneas del juego de caracteres de PC original no están ahí en ANSI, y porque los caracteres nacionales tienen códigos diferentes en ANSI. Pero oye, ¿quién usa los viejos programas de DOS? ¡Yo no!

Si desea esto como una página de códigos más permanente, usted tiene que cambiar la configuración de las ventanas de la consola a través de una clave de registro no documentada:

HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ NLS \ CodePage

En esta clave, el valor de cambio de OEMCP a 1252, y reinicio.

Al igual que con chcp, u otro cambio de página de códigos a 1252, hace que los viejos programas de DOS presenten gobbledegook, pero hace que los programas C++ u otros programas modernos de la consola funcionen correctamente.

Dado que tiene la misma codificación de caracteres en las ventanas de la consola que en el resto de Windows.

0

es probable que sea implementada utilizando un juego de caracteres ASCII básico. Los programadores de Microsoft no agregaron la capacidad de utf-8 al crear la consola. Solo una suposición ya que no era un programador de Microsoft involucrado en la creación de la consola.

+2

puede enviar utf-8 a la consola de Windows. –

3

Cuando imprime una cadena ASCII, Windows la convierte internamente en UNICODE según la página de códigos actual. También hay una traducción de UNICODE a "ASCII" realizada por el CRT. Lo siguiente funcionaría.

#include <fcntl.h> 
#include <io.h> 
#include <stdio.h> 
#include <iostream> 

void 
__cdecl 
main(int ac, char **av) 
{ 
    _setmode(_fileno(stdout), _O_U16TEXT); 
    std::wcout << L"\u00BF"; 
} 
+0

Devuelve el mismo resultado. – user3234

+0

Con la llamada _setmode esto funcionaría. Probado. – John

2

Debido a que la consola Win32 utiliza code page 437 (también conocido como la fuente OEM) para representar los caracteres, mientras que la mayor parte del resto de Windows utiliza Windows-1252 de códigos de caracteres de un solo byte.

El carácter "¿" es el carácter Unicode MARCA DE PREGUNTA INVERTIDA, que tiene un punto de código 0xBF (191 decimal) en Unicode, ISO 8859-1 y Windows-1252. El punto de código 0xBF en CP437 corresponde al carácter "┐", que es LUZ DE DIBUJOS DE CAJA HACIA ABAJO E IZQUIERDA (punto de código U + 2510).

Siempre que use la consola de Windows, puede mostrar solo los caracteres en CP437 y no en otros. Si desea visualizar otros caracteres Unicode, deberá usar un entorno diferente.

+3

puede mostrar unicode en la consola de Windows. –

Cuestiones relacionadas