2009-09-03 41 views
16

Para una aplicación de consola C++ compilada con Visual Studio 2008 en inglés Windows (XP, Vista o 7). ¿Es posible imprimir en la consola y mostrar correctamente el japonés codificado en UTF-8 usando cout o wcout?Cómo imprimo UTF-8 desde la aplicación de consola C++ en Windows

+2

Hay un hilo interesante en cplusplus.com: UTF-8 en línea de comandos (consola) http://www.cplusplus.com/forum/windows/9797/ – anno

+0

** Recién llegados: ** [Verifique mi respuesta aquí] (http://stackoverflow.com/a/40337240/3258851) sobre el uso de Unicode - y marque [esta respuesta] (http://stackoverflow.com/a/26479960/ 3258851) al cambiar la fuente de la consola. –

Respuesta

0

En la consola, ingrese chcp 65001 para cambiar la página de códigos a la de UTF-8.

7

La consola de Windows usa el OEM code page de forma predeterminada para mostrar la salida.

Para cambiar la página de códigos Unicode a entrar chcp 65001 en la consola, o tratar de cambiar la página de códigos mediante programación con SetConsoleOutputCP.

Tenga en cuenta que probablemente tenga que cambiar la fuente de la consola a una que tenga glifos en el rango Unicode.

+4

Tenga en cuenta que hay muchos errores con UTF-8 como página de códigos. La mayoría son WONTFIX. – Deduplicator

4

Nunca he intentado configurar la página de códigos de la consola en UTF8 (no estoy seguro de por qué no funcionaría ... la consola puede manejar otras páginas de códigos de varios bytes), pero hay un par de funciones para buscar: SetConsoleCP y SetConsoleOutputCP.

Probablemente también deba asegurarse de estar utilizando una fuente de consola que sea capaz de mostrar sus caracteres. Está la función SetCurrentConsoleFontEx, pero solo está disponible en Vista y más arriba.

Espero que ayude.

+2

Pruebe la fuente Lucida Console. – anno

4

Here's an article from MVP Michael Kaplan cómo salir correctamente de UTF-16 a través de la consola. Puede convertir su UTF-8 a UTF-16 y generarlo.

+2

Una observación: Michael Kaplan no es un MVP. No sé si alguna vez lo fue. Ha sido empleado de Microsoft por mucho tiempo (los empleados de Microsoft no son elegibles para el programa MVP). –

+0

Este enlace trae a _Resource Not Found_. – Salvador

+0

A partir del 2016-08-09, el enlace redirecciona a http://archives.miloush.net/michkap/archive/2008/03/18/8306597.html pero hay material presente (presumiblemente lo que originalmente estaba en siao2.com) –

1

Consola de inicio de aplicación establecida en CP OEM437 por defecto. Estaba intentando enviar texto Unicode a stdout, donde la consola cambió a la traducción UTF8 _setmode (_fileno (stdout), _O_U8TEXT); y aún no tuvo suerte en la pantalla, incluso con la fuente Lucida TT. Si la consola se redirigió a un archivo, se crearon los archivos UTF8 correctos.

Finalmente tuve suerte. He agregado una sola línea "info.FontFamily = FF_DONTCARE;" y está funcionando ahora. Espero que esta ayuda para usted.

void SetLucidaFont() 
{ 
    HANDLE StdOut = GetStdHandle(STD_OUTPUT_HANDLE); 
    CONSOLE_FONT_INFOEX info; 
    memset(&info, 0, sizeof(CONSOLE_FONT_INFOEX)); 
    info.cbSize = sizeof(CONSOLE_FONT_INFOEX);    // prevents err=87 below 
    if (GetCurrentConsoleFontEx(StdOut, FALSE, &info)) 
    { 
     info.FontFamily = FF_DONTCARE; 
     info.dwFontSize.X = 0; // leave X as zero 
     info.dwFontSize.Y = 14; 
     info.FontWeight = 400; 
     _tcscpy_s(info.FaceName, L"Lucida Console"); 
     if (SetCurrentConsoleFontEx(StdOut, FALSE, &info)) 
     { 
     } 
    } 
} 
2

Esto debería funcionar:

#include <cstdio> 
#include <windows.h> 

#pragma execution_character_set("utf-8") 

int main() 
{ 
    SetConsoleOutputCP(65001); 
    printf("Testing unicode -- English -- Ελληνικά -- Español -- Русский. aäbcdefghijklmnoöpqrsßtuüvwxyz\n"); 
} 

No sabe si afecta a nada, pero el archivo de origen se guarda como Unicode (UTF-8 con firma) - Página de códigos 65001 en ARCHIVO ->Opciones de guardado avanzadas ....

Proyecto -> Propiedades -> Propiedades de configuración ->general ->juego de caracteres se establece en Unicode Uso de conjuntos de caracteres.

Algunos dicen que necesita para cambiar la fuente de la consola para Lucida Console, pero de mi parte que se muestra con tanto Consolas y Lucida Console.

+0

Usando el código página 1252 (latín 1), esto funciona. – someonewithpc

1

Sólo para información adicional:

'ANSI' se refiere a las ventanas-125x, que se utiliza para aplicaciones Win32, mientras que 'OEM' se refiere a la página de códigos utilizada por aplicaciones/MS-DOS consola.
Las páginas de códigos activos actuales se pueden recuperar con las funciones GetOEMCP() y GetACP().

Con el fin de demostrar algo correctamente a la consola, debe:

  1. garantizar la página actual de códigos OEM compatible con los caracteres que desee a la salida
    (si es necesario, utilizar SetConsoleOutputCP para configurarlo adecuadamente)

  2. convertir la cadena de código ANSI actual (Win32) a la página de códigos OEM consola

Estas son algunas utilidades para hacerlo:

// Convert a UTF-16 string (16-bit) to an OEM string (8-bit) 
#define UNICODEtoOEM(str) WCHARtoCHAR(str, CP_OEMCP) 

// Convert an OEM string (8-bit) to a UTF-16 string (16-bit) 
#define OEMtoUNICODE(str) CHARtoWCHAR(str, CP_OEMCP) 

// Convert an ANSI string (8-bit) to a UTF-16 string (16-bit) 
#define ANSItoUNICODE(str) CHARtoWCHAR(str, CP_ACP) 

// Convert a UTF-16 string (16-bit) to an ANSI string (8-bit) 
#define UNICODEtoANSI(str) WCHARtoCHAR(str, CP_ACP) 


/* Convert a single/multi-byte string to a UTF-16 string (16-bit). 
We take advantage of the MultiByteToWideChar function that allows to specify the charset of the input string. 
*/ 
LPWSTR CHARtoWCHAR(LPSTR str, UINT codePage) { 
    size_t len = strlen(str) + 1; 
    int size_needed = MultiByteToWideChar(codePage, 0, str, len, NULL, 0); 
    LPWSTR wstr = (LPWSTR) LocalAlloc(LPTR, sizeof(WCHAR) * size_needed); 
    MultiByteToWideChar(codePage, 0, str, len, wstr, size_needed); 
    return wstr; 
} 


/* Convert a UTF-16 string (16-bit) to a single/multi-byte string. 
We take advantage of the WideCharToMultiByte function that allows to specify the charset of the output string. 
*/ 
LPSTR WCHARtoCHAR(LPWSTR wstr, UINT codePage) { 
    size_t len = wcslen(wstr) + 1; 
    int size_needed = WideCharToMultiByte(codePage, 0, wstr, len, NULL, 0, NULL, NULL); 
    LPSTR str = (LPSTR) LocalAlloc(LPTR, sizeof(CHAR) * size_needed); 
    WideCharToMultiByte(codePage, 0, wstr, len, str, size_needed, NULL, NULL); 
    return str; 
} 
Cuestiones relacionadas