What is the best way to output Unicode to console?

核能气质少年 提交于 2020-04-16 02:47:51

问题


I am working with C++17 in Visual Studio 2019. I have read a fair bit about encodings but I am still not very comfortable with them. I want to output UNICODE characters to screen. For that, I am using the following code

#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

So I could do setmode to _O_WTEXT and then back to O_TEXT everytime I need to output the std::wstring. However, I am worried this may be an inefficient way to do things. Is there a better way to do it? I have read about something called native widechar support in C++ but I found it hard to understand. Could anyone illuminate me?

EDIT

To add to the above, using _setmode(_fileno(stdout),_O_U16TEXT) leads to the same behaviour as described above when trying to use std::cout without setting the mode back. If I use _setmode(_fileno(stdout),_O_U8TEXT) instead, my code fails to compile and gives errors 'symbol': redefinition, different basic types and '<<': illegal for class when using std::cout on std::string symbol = <insert any of the possibilities I tried in the snippet below>.

I have been suggested to use a UTF-8 std::string to be able to use std::cout and that way avoid having to switch to wide mode. Could anyone give me a hand on how to achieve this? I have tried

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)

I have read it may be possible to convert from std::wstring to UTF-8 std::string using WideCharToMultiByte() from the header <Windows.h>. Would that work? Could anyone offer any help?


回答1:


The clue is in the error message. "...cannot be represented in the current code page (1252)". So the code page needs to be changed. The code page identifier for UTF-8 is 65001. To change the code page, use SetConsoleOutputCP.



来源:https://stackoverflow.com/questions/61063497/what-is-the-best-way-to-output-unicode-to-console

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!