Как распечатать UTF-8 из консольного приложения С++ в Windows

Для консольного приложения С++, скомпилированного с Visual Studio 2008 на английском языке Windows (XP, Vista или 7). Можно ли распечатать на консоли и правильно отобразить японский язык с кодировкой UTF-8 с помощью cout или wcout?

Ответы

Ответ 1

Консоль Windows использует OEM-страницу кода по умолчанию для вывода вывода.

Чтобы изменить кодовую страницу на Unicode, введите chcp 65001 в консоли или попробуйте программно изменить кодовую страницу с помощью SetConsoleOutputCP.

Обратите внимание, что вам, вероятно, придется изменить шрифт консоли на тот, у которого есть глифы в диапазоне Unicode.

Ответ 3

Я никогда не пытался настроить кодовую страницу консоли на UTF8 (не уверен, почему это не сработает... консоль может обрабатывать другие многобайтовые кодовые страницы просто отлично), но есть пара функции для поиска: SetConsoleCP и SetConsoleOutputCP.

Возможно, вам также понадобится убедиться, что вы используете консольный шрифт, который способен отображать ваши персонажи. Там SetCurrentConsoleFontEx функция, но она доступна только в Vista и выше.

Надеюсь, что это поможет.

Ответ 4

Это должно работать:

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

Не знаю, влияет ли это на что-либо, но исходный файл сохраняется как Unicode (UTF-8 с сигнатурой) - Codepage 65001 в ФАЙЛ Расширенные параметры сохранения....

Проект Свойства Свойства конфигурации Общие Набор символов установлено значение Использовать набор символов Unicode.

Некоторые говорят, что вам нужно изменить консольный шрифт на Lucida Console, но на моей стороне он отображается как с Consolas, так и с Lucida Console.

Ответ 5

В консоли запуска приложения установлено значение по умолчанию для OEM437 CP. Я пытался вывести текст Unicode в stdout, где консоль переключилась на перевод UTF8 _setmode (_fileno (stdout), _O_U8TEXT); и до сих пор не повезло на экране даже с шрифтом Lucida TT. Если консоль была перенаправлена ​​в файл, был создан файл UTF8.

Наконец мне повезло. Я добавил одну строку "info.FontFamily = FF_DONTCARE;" и он работает сейчас. Надейтесь, что это поможет вам.

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))
        {
        }
    }
}

Ответ 6

Только для дополнительной информации:

"ANSI" относится к окнам-125x, которые используются для приложений win32, в то время как "OEM" относится к кодовой странице, используемой консольными/MS-DOS-приложениями.
Текущие активные кодовые страницы могут быть получены с помощью функций GetOEMCP() и GetACP().

Чтобы вывести что-то правильно на консоль, вы должны:

  • убедитесь, что текущая кодовая страница OEM поддерживает символы, которые вы хотите вывести
    (при необходимости используйте SetConsoleOutputCP, чтобы установить его правильно)

  • преобразовать строку из текущего кода ANSI (win32) в кодовую страницу OEM-сервера консоли

Вот несколько утилит для этого:

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

Ответ 7

В консоли введите chcp 65001, чтобы изменить кодовую страницу на UTF-8.