问题
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