2009-09-03 5 views
16

Pour une application de console C++ compilée avec Visual Studio 2008 sur Windows anglais (XP, Vista ou 7). Est-il possible d'imprimer sur la console et d'afficher correctement le japonais codé en UTF-8 en utilisant cout ou wcout?Comment imprimer UTF-8 à partir d'une application de console C++ sous Windows

+2

Il y a un fil intéressant à cplusplus.com: UTF-8 dans l'invite de commande (console) http://www.cplusplus.com/forum/windows/9797/ – anno

+0

** Nouveaux arrivants: ** [Vérifier ma réponse ici] (http://stackoverflow.com/a/40337240/3258851) sur l'utilisation d'unicode - et cochez [cette réponse] (http://stackoverflow.com/a/26479960/ 3258851) sur la modification de la police de la console. –

Répondre

0

Dans la console, entrez chcp 65001 pour remplacer la page de codes par celle de UTF-8.

7

La console Windows utilise le OEM code page par défaut pour afficher la sortie.

Pour modifier la page de code Unicode entrer chcp 65001 dans la console, ou d'essayer de modifier la page de code programme avec SetConsoleOutputCP.

Notez que vous devez probablement remplacer la police de la console par celle qui a des glyphes dans la plage Unicode.

+4

Sachez qu'il existe de nombreux bogues avec UTF-8 comme page de codes. La plupart sont WONTFIX. – Deduplicator

4

Je n'ai jamais vraiment essayé de paramétrer la page de code de la console en UTF8 (je ne sais pas pourquoi cela ne fonctionnerait pas ... la console peut gérer d'autres pages de code multi-octets), mais il y a quelques des fonctions à rechercher: SetConsoleCP et SetConsoleOutputCP.

Vous devrez probablement également vous assurer que vous utilisez une police de console capable d'afficher vos caractères. Il y a la fonction SetCurrentConsoleFontEx, mais elle n'est disponible que sur Vista et au dessus.

Espérons que ça aide.

+2

Essayez la police Lucida Console. – anno

4

Here's an article from MVP Michael Kaplan sur comment correctement sortir UTF-16 à travers la console. Vous pouvez convertir votre UTF-8 en UTF-16 et le sortir.

+2

Une observation: Michael Kaplan n'est pas un MVP. Je ne sais pas s'il l'a déjà été. Il a été employé de Microsoft pendant des années (les employés de Microsoft ne sont pas éligibles pour le programme MVP). –

+0

Ce lien mène à _Resource Not Found_. – Salvador

+0

En date du 2016-08-09, le lien redirige vers http://archives.miloush.net/michkap/archive/2008/03/18/8306597.html mais il y a du matériel présent (vraisemblablement ce qui était à l'origine sur siao2.com)). –

1

La console de démarrage de l'application est définie sur CP OEM437 par défaut. J'essayais de sortir du texte Unicode vers stdout, où la console passait à _setmode de traduction UTF8 (_fileno (stdout), _O_U8TEXT); et n'avait toujours pas de chance sur l'écran même avec la police Lucida TT. Si la console a été redirigée vers le fichier, le fichier UTF8 correct a été créé.

Finalement, j'ai eu de la chance. J'ai ajouté une seule ligne "info.FontFamily = FF_DONTCARE;" et ça marche maintenant. J'espère que cette aide vous sera utile.

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

Cela devrait fonctionner:

#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"); 
} 

Je ne sais pas si elle affecte quelque chose, mais le fichier source est enregistré en tant que Unicode (UTF-8 avec signature) - Codepage 65001 à FICHIER ->Options d'enregistrement avancées ....

Projet -> Propriétés -> Propriétés de configuration -> Général -> Jeu de caractères est réglé sur Utiliser Unicode Jeu de caractères.

Certains disent que vous devez changer la police de la console à Lucida Console, mais de mon côté, il est affiché à la fois Consolas et Lucida Console.

+0

En utilisant la page de code 1252 (latin 1), cela marche. – someonewithpc

1

Juste Pour plus d'informations:

'ANSI' fait référence aux fenêtres 125x, utilisé pour les applications win32 tandis que 'OEM' fait référence à la page de code utilisé par les applications de la console/MS-DOS.
Les pages de codes actives actuelles peuvent être récupérées avec les fonctions GetOEMCP() et GetACP().

Pour afficher quelque chose correctement à la console, vous devez:

  1. assurer la page de code OEM prend en charge les caractères que vous voulez à la sortie
    (si nécessaire, utilisez SetConsoleOutputCP pour le définir correctement)

  2. convertir la chaîne à partir du code actuel ANSI (win32) à la page de code OEM console

Voici quelques utilitaires pour le faire:

// 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; 
} 
Questions connexes