Comment imprimer UTF-8 à partir de l'application c++ console sur Windows

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

17
demandé sur Paul Dixon 2009-09-03 05:25:39

7 réponses

la console Windows utilise le page de codes OEM par défaut pour afficher la sortie.

pour changer la page de code en Unicode entrez chcp 65001 dans la console, ou essayer de changer la page de code par programmation avec SetConsoleOutputCP.

notez que vous devez probablement changer la police de la console pour une qui a des glyphes dans la gamme unicode.

8
répondu dtb 2009-09-03 01:55:38

voici un article du MVP Michael Kaplan sur la façon de sortir correctement UTF-16 à travers la console. Vous pouvez convertir votre UTF-8 en UTF-16 et produire cela.

5
répondu sbi 2014-10-08 17:08:08

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

vous aurez probablement aussi besoin de vous assurer que vous utilisez une police de la console capable d'afficher vos caractères. Il y a le SetCurrentConsoleFontEx fonction, mais il n'est disponible que sur Vista et surtout.

J'espère que ça aidera.

4
répondu ijprest 2009-09-03 02:04:50

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 cela affecte quelque chose, mais le fichier source est sauvegardé comme Unicode (UTF-8 avec signature) - page de Codes 65001 FILE -> Options Avancées De Sauvegarde ....

Projet -> Propriétés -> Propriétés De Configuration -> Généralités -> Jeu De Caractères est réglé sur Utiliser Le Caractère Unicode Set.

certains disent que vous devez changer la police de la console en Lucida Console, mais de mon côté il est affiché avec les deux Consolas et Lucida Console.

2
répondu Slav 2016-02-23 11:46:34

sur l'application démarrer la console réglée à la CP par défaut OEM437. J'ai essayé de sortir du texte Unicode vers stdout, où la console était commuté en UTF8 traduction _setmode(_fileno(stdout), _O_U8TEXT); et toujours pas de chance sur l'écran, même avec Lucida TT font. Si la console était redirigée vers le fichier, le fichier UTF8 correct était créé.

finalement j'ai eu de la chance. J'ai ajouté une ligne info.FontFamily = FF_DONTCARE;" et il travaille maintenant. Espérons que cette aide pour vous.

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))
        {
        }
    }
}
1
répondu adspx5 2015-11-20 00:55:26

pour plus d'informations:

'ANSI' se réfère à windows-125x, utilisé pour les applications win32 tandis que' OEM ' se réfère à la page de code utilisée par les applications console/MS-DOS.

Les pages de code actives actuelles peuvent être récupérées avec les fonctions GetOEMCP() et GetACP().

pour afficher correctement quelque chose sur la console, vous devez:

  1. assurez-vous que la page de code OEM actuelle supporte les caractères que vous voulez sortie

    (si nécessaire, utilisez SetConsoleOutputCP pour le définir correctement)

  2. convertissez la chaîne du code ANSI courant (win32) à la page de Code OEM de la 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;
}
1
répondu Cédric Françoys 2016-03-11 20:02:26

Dans la console, entrez chcp 65001 pour changer la page de code en UTF-8.

0
répondu Alan Haggai Alavi 2009-09-03 01:49:27