Использование юникода в консоли

149
13 декабря 2018, 05:40

Работаю MS VS 201, Win 7. Следующий код выводит не тот символ, какой надо:

system("chcp 65001");
std::cout << "\x00FF" << std::endl;

В чем проблема? Консоль не дружит с юникодом даже после смены codepage-а?

Answer 1

Нет, консоль Windows дружит с юникодом без необходимости задавать кодовую страницу. В этом легко убедиться, запустив такой код:

HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
wchar_t str[]=L"\x00FF\n";
WriteConsoleW(consoleHandle,str,wcslen(str),NULL,NULL);

Однако, это не решает проблему, так как это работает только с консолью. Если стандартный вывод перенаправлен в файл, все нарушается. Можно перейти с WriteConsole на WriteFile, но это не очень удобно.

Если нужно именно UTF-8, в VS 2015+ работает так:

#include <string>
#include <iostream>
#include <Windows.h>
#include <cstdio>
int main() {
    SetConsoleOutputCP(CP_UTF8);    
    setvbuf(stdout, NULL, _IOFBF, 1000);
    std::cout << u8"\x00FF" << std::endl;
}

Более традиционный способ, поддерживаемый VS2010+, это все же использовать промежуточно широкие символы:

#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <io.h>
#include <fcntl.h>
#include <iostream>
int main()
{    
    _setmode(_fileno(stdout),  _O_U8TEXT);
    std::wcout << L"\x00FF" << std::endl;    
}
Answer 2

Перед запуском убедитесь что шрифт в консоли поддерживает данный символ.

#include <io.h> 
#include <iostream> //debug
#include <fcntl.h>
int wmain(int argc, wchar_t* argv[])
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_U16TEXT);
    _setmode(_fileno(stderr), _O_U16TEXT);
    std::wcout << L"\x00FF" << std::endl;
    system("pause");
    return 0;
}
READ ALSO
C++ WinApi Качество рисования

C++ WinApi Качество рисования

Если например рисовать круг на окне, то он получается нечетким, как рисовать/рендерить более точно неровные примитивы?

168
Специализация шаблонного класса

Специализация шаблонного класса

Есть шаблонный класс:

134
Генерация больших целых значений

Генерация больших целых значений

Как сгенерировать значения, допустим от 10000 до 99999? Используя Mathrandom() проскакивают четырех-,шести- значные

173
Помогите найти ошибку в методе

Помогите найти ошибку в методе

Есть массив заполненный числами от 1 до 100 с пропущенным числом 46, путем сложения первого и последнего элемента идет поиск пропущенного элемента,...

267