Каков наилучший способ вывода Unicode на консоль? - PullRequest
2 голосов
/ 06 апреля 2020

Я работаю с C ++ 17 в Visual Studio 2019. Я немного прочитал о кодировках, но мне все еще не очень удобно с ними. Я хочу выводить символы UNICODE на экран. Для этого я использую следующий код

#include <iostream>
#include <fcntl.h>
#include <io.h>

std::wstring symbol{ L"♚" };

_setmode(_fileno(stdout), _O_WTEXT);
std::wcout << symbol; //This works fine
std::cout << "Hello"; //This gives "Debug Assertion Failed! Expression: buffer_size % 2 == 0"
_setmode(_fileno(stdout), O_TEXT); //Need this to make std::cout work normally
std::cout << "World"; //This works fine

Так что я могу сделать setmode для _O_WTEXT и затем возвращаться к O_TEXT каждый раз, когда мне нужно вывести std :: wstring. Тем не менее, я беспокоюсь, что это может быть неэффективным способом сделать что-то. Есть ли лучший способ сделать это? Я читал о том, что в C ++ называется родной поддержкой widechar, но мне было трудно это понять. Может ли кто-нибудь осветить меня?

РЕДАКТИРОВАТЬ

Чтобы добавить к вышесказанному, использование _setmode(_fileno(stdout),_O_U16TEXT) приводит к тому же поведению, как описано выше, при попытке использовать std::cout без вернуть режим обратно. Если вместо этого я использую _setmode(_fileno(stdout),_O_U8TEXT), мой код не компилируется и выдает ошибки 'symbol': redefinition, different basic types и '<<': illegal for class при использовании std::cout на std::string symbol = <insert any of the possibilities I tried in the snippet below>.

Мне предложили использовать UTF-8 std::string, чтобы можно было использовать std::cout и таким образом избегать необходимости переключаться в широкоэкранный режим. Кто-нибудь может мне помочь, как этого добиться? Я пытался

std::string symbol = "\u265A"; //using std::cout gives "?" and triggers warning *
std::string symbol = "♚"; //Same as above

std::string symbol = u8"\u265A"; //using std::cout gives "ÔÖÜ"
std::string symbol = u8"♚"; //Same as above

*Severity Code Description Project File Line Suppression State Warning C4566 character represented by universal-character-name '\u265A' cannot be represented in the current code page (1252)

Я читал, что возможно преобразовать из std::wstring в UTF-8 std::string с помощью WideCharToMultiByte () из заголовка <Windows.h>. Будет ли это работать? Может ли кто-нибудь предложить какую-либо помощь?

1 Ответ

1 голос
/ 14 апреля 2020

Подсказка в сообщении об ошибке. msgstr "... не может быть представлено в текущей кодовой странице (1252)". Таким образом, кодовая страница должна быть изменена. идентификатор кодовой страницы для UTF-8 - 65001. Чтобы изменить кодовую страницу, используйте SetConsoleOutputCP.

...