wake-up-neo.com

Ausgabe von Unicode-Strings in der Windows-Konsolen-App

Hallo, ich habe versucht, Unicode-Zeichenfolge mit iostreams an eine Konsole auszugeben und ist fehlgeschlagen.

Ich habe folgendes gefunden: Unicode-Schriftart in der C++ - Konsolen-App verwenden und dieses Snippet funktioniert.

SetConsoleOutputCP(CP_UTF8);
wchar_t s[] = L"èéøÞǽлљΣæča";
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
wprintf(L"%S", m);

Ich habe jedoch keinen Weg gefunden, Unicode korrekt mit Iostreams auszugeben. Irgendwelche Vorschläge?

Das funktioniert nicht:

SetConsoleOutputCP(CP_UTF8);
utf8_locale = locale(old_locale,new boost::program_options::detail::utf8_codecvt_facet());
wcout.imbue(utf8_locale);
wcout << L"¡Hola!" << endl;

EDIT Ich konnte keine andere Lösung finden, als dieses Snippet in einem Stream zu verpacken. Ich hoffe, jemand hat bessere Ideen.

//Unicode output for a Windows console 
ostream &operator-(ostream &stream, const wchar_t *s) 
{ 
    int bufSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
    char *buf = new char[bufSize];
    WideCharToMultiByte(CP_UTF8, 0, s, -1, buf, bufSize, NULL, NULL);
    wprintf(L"%S", buf);
    delete[] buf; 
    return stream; 
} 

ostream &operator-(ostream &stream, const wstring &s) 
{ 
    stream - s.c_str();
    return stream; 
} 
68
Andrew

Ich habe hier eine Lösung mit Visual Studio 2010 verifiziert. Über diesen MSDN-Artikel und MSDN-Blogbeitrag . Der Trick ist ein obskurer Aufruf an _setmode(..., _O_U16TEXT).

Lösung:

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

int wmain(int argc, wchar_t* argv[])
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    std::wcout << L"Testing unicode -- English -- Ελληνικά -- Español." << std::endl;
}

Bildschirmfoto:

Unicode in console

81
DuckMaestro

Unicode Hello World auf Chinesisch

Hier ist eine Hallo Welt auf Chinesisch. Eigentlich ist es nur "Hallo". Ich habe dies unter Windows 10 getestet, aber ich denke, dass es seit Windows Vista funktionieren könnte. Vor Windows Vista wird es hart sein, wenn Sie eine programmatische Lösung haben möchten, anstatt die Konsole/Registry usw. zu konfigurieren Sie müssen dies unter Windows 7 wirklich tun: Konsole ändern Windows 7 ändern

Ich möchte nicht behaupten, dass dies die einzige Lösung ist, aber das hat bei mir funktioniert.

Gliederung

  1. Unicode-Projekteinrichtung
  2. Legen Sie die Konsolen-Codepage auf Unicode fest
  3. Suchen und verwenden Sie eine Schriftart, die die anzuzeigenden Zeichen unterstützt
  4. Verwenden Sie das Gebietsschema der Sprache, die Sie anzeigen möchten
  5. Verwenden Sie die Breitzeichenausgabe, d. H. std::wcout

1 Projekteinrichtung

Ich verwende Visual Studio 2017 CE. Ich habe eine leere Konsolen-App erstellt. Die Standardeinstellungen sind in Ordnung. Wenn Sie jedoch Probleme haben oder eine andere Idee verwenden, sollten Sie diese überprüfen:

In Ihren Projekteigenschaften finden Sie Konfigurationseigenschaften -> Allgemein -> Projekteinstellungen -> Zeichensatz. Es sollte "Unicode-Zeichensatz verwenden" und nicht "Multi-Byte" verwendet werden Dadurch werden für Sie _UNICODE- und UNICODE-Präprozessor-Makros definiert.

int wmain(int argc, wchar_t* argv[])

Ich denke auch, wir sollten die wmain-Funktion anstelle von main verwenden. Beide funktionieren, aber in einer Unicode-Umgebung ist wmain möglicherweise bequemer.

Auch meine Quelldateien sind UTF-16-LE-codiert. Dies scheint in Visual Studio 2017 die Standardeinstellung zu sein.

2. Konsolen-Codepage

Das ist ganz offensichtlich. Wir benötigen die Unicode-Codepage in der Konsole . Wenn Sie Ihre Standard-Codepage überprüfen möchten, öffnen Sie einfach eine Konsole und geben Sie chcp ohne Argumente ..__ ein. Wir müssen sie in 65001 ändern (UTF-8-Codepage) . Windows Codepage-Bezeichner Für diese Codepage gibt es ein Präprozessor-Makro: CP_UTF8. Ich musste sowohl die Eingabe- als auch die Ausgabeseite einstellen. Wenn ich eines weggelassen habe, war die Ausgabe falsch.

SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);

Möglicherweise möchten Sie auch die booleschen Rückgabewerte dieser Funktionen überprüfen.

3. Wählen Sie eine Schrift

Bis jetzt habe ich keine Konsolenschrift gefunden, die jedes Zeichen unterstützt. Also musste ich einen auswählen. Wenn Sie Zeichen ausgeben möchten, die teilweise nur in einer Schriftart und teilweise in einer anderen Schriftart verfügbar sind, dann glaube ich, dass es unmöglich ist, eine Lösung zu finden. Nur vielleicht, wenn es eine Schriftart gibt, die jedes Zeichen unterstützt. Aber auch ich habe nicht nachgedacht, wie man eine Schrift installiert.

Ich denke, es ist nicht möglich, zwei verschiedene Schriftarten gleichzeitig in demselben Konsolenfenster zu verwenden.

So finden Sie eine kompatible Schrift? Öffnen Sie Ihre Konsole, und wechseln Sie zu den Eigenschaften des Konsolenfensters, indem Sie auf das Symbol oben links im Fenster klicken. Gehen Sie zur Registerkarte Schriftarten, wählen Sie eine Schrift und klicken Sie auf OK. Versuchen Sie dann, Ihre Zeichen in das Konsolenfenster einzugeben. Wiederholen Sie dies, bis Sie eine Schriftart gefunden haben, mit der Sie arbeiten können. Notieren Sie sich dann den Namen der Schrift.

Sie können auch die Größe der Schriftart im Eigenschaftenfenster ändern. Wenn Sie eine Größe gefunden haben, mit der Sie zufrieden sind, notieren Sie sich die Größenwerte, die im Eigenschaftenfenster im Abschnitt "ausgewählte Schriftart" angezeigt werden. Breite und Höhe werden in Pixel angezeigt.

Um die Schrift programmgesteuert zu setzen, verwenden Sie:

CONSOLE_FONT_INFOEX fontInfo;
// ... configure fontInfo
SetCurrentConsoleFontEx(hConsole, false, &fontInfo);

Einzelheiten dazu finden Sie in meinem Beispiel am Ende dieser Antwort. Oder schauen Sie im feinen Handbuch nach: SetCurrentConsoleFont . Diese Funktion gibt es nur seit Windows Vista.

4. Legen Sie das Gebietsschema fest

Sie müssen das Gebietsschema auf das Gebietsschema der Sprache einstellen, für die die Zeichen gedruckt werden sollen.

char* a = setlocale(LC_ALL, "chinese");

Der Rückgabewert ist interessant. Es wird eine Zeichenfolge enthalten, die genau beschreibt, welches Gebietsschema ausgewählt wurde . Probieren Sie es einfach aus: -) Ich habe es mit chinese und german. Getestet. Weitere Informationen: setlocale

5. Verwenden Sie eine Breitzeichenausgabe

Hier nicht viel zu sagen ... Wenn Sie breite Zeichen ausgeben möchten, verwenden Sie diese zum Beispiel:

std::wcout << L"你好" << std::endl;

Oh, und vergessen Sie nicht das L-Präfix für breite Zeichen! Und wenn Sie in der Quelldatei literale Unicode-Zeichen wie diese eingeben, muss die Quelldatei Unicode-codiert sein. Der Standard in Visual Studio ist UTF-16-LE. Oder verwenden Sie notepad ++ und setzen Sie die Kodierung auf UCS-2 LE BOM.

Beispiel

Zum Schluss habe ich alles als Beispiel zusammengestellt:

#include <Windows.h>
#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <locale.h>
#include <wincon.h>

int wmain(int argc, wchar_t* argv[])
{
    SetConsoleTitle(L"My Console Window - 你好");
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);

    char* a = setlocale(LC_ALL, "chinese");
    SetConsoleOutputCP(CP_UTF8);
    SetConsoleCP(CP_UTF8);

    CONSOLE_FONT_INFOEX fontInfo;
    fontInfo.cbSize = sizeof(fontInfo);
    fontInfo.FontFamily = 54;
    fontInfo.FontWeight = 400;
    fontInfo.nFont = 0;
    const wchar_t myFont[] = L"KaiTi";
    fontInfo.dwFontSize = { 18, 41 };
    std::copy(myFont, myFont + (sizeof(myFont) / sizeof(wchar_t)), fontInfo.FaceName);

    SetCurrentConsoleFontEx(hConsole, false, &fontInfo);

    std::wcout << L"Hello World!" << std::endl;
    std::wcout << L"你好!" << std::endl;
    return 0;
}

Prost !

4
David

Für das wcout muss das Gebietsschema anders als das CRT eingestellt sein. So kann es behoben werden:

int _tmain(int argc, _TCHAR* argv[])
{
    char* locale = setlocale(LC_ALL, "English"); // Get the CRT's current locale.
    std::locale lollocale(locale);
    setlocale(LC_ALL, locale); // Restore the CRT.
    std::wcout.imbue(lollocale); // Now set the std::wcout to have the locale that we got from the CRT.
    std::wcout << L"¡Hola!";
    std::cin.get();
    return 0;
}

Ich habe es gerade getestet, und es zeigt die Saite hier absolut in Ordnung.

3
Puppy

SetConsoleCP () und chcp macht das nicht gleich!

Nehmen Sie diesen Programmausschnitt:

SetConsoleCP(65001)  // 65001 = UTF-8
static const char s[]="tränenüberströmt™\n";
DWORD slen=lstrlen(s);
WriteConsoleA(GetStdHandle(STD_OUTPUT_HANDLE),s,slen,&slen,NULL);

Der Quellcode muss als UTF-8 gespeichert werden ohne Stückliste (Byte Order Mark; Unterschrift). Dann der Microsoft-Compiler cl.exe Nimmt die UTF-8-Zeichenfolgen wie sie sind.
Wenn dieser Code gespeichert ist mit BOM, cl.exe wandelt den String in ANSI (d. H. CP1252) um, der nicht mit CP65001 (= UTF-8) übereinstimmt.

Ändern Sie die Anzeigeschrift in Lucidia ConsoleAndernfalls funktioniert die UTF-8-Ausgabe überhaupt nicht.

  • Typ: chcp
  • Antwort: 850
  • Typ: test.exe
  • Antwort: tr├ñnen├╝berstr├ÂmtÔäó
  • Typ: chcp
  • Antwort: 65001 - Diese Einstellung wurde um SetConsoleCP() geändert, hat jedoch keinen nützlichen Effekt.
  • Typ: chcp 65001
  • Typ: test.exe
  • Antwort: tränenüberströmt™ - Alles OK jetzt.

Getestet mit: Deutsch Windows XP SP3

2
Henrik Haftmann

Ich wollte vor kurzem Unicode von Python auf die Windows-Konsole streamen. Hier ist das Minimum, das ich machen musste:

  • Sie sollten die Konsolenschriftart auf die Schriftart für Unicode-Symbole einstellen. Es gibt keine große Auswahl: Konsolen-Eigenschaften> Schriftart> Lucida-Konsole
  • Sie sollten die aktuelle Konsolen-Codepage ändern: Führen Sie chcp 65001 in der Konsole aus oder verwenden Sie die entsprechende Methode im C++ - Code
  • schreiben Sie mit WriteConsoleW an die Konsole 

Durchsuchen Sie einen interessanten Artikel über Java-Unicode auf der Windows-Konsole

In Python können Sie in diesem Fall nicht in die Standardeinstellung sys.stdout schreiben. In diesem Fall müssen Sie es mit os.write (1, binarystring) oder mit einem direkten Wrapper um WriteConsoleW ersetzen. Anscheinend müssen Sie in C++ dasselbe tun.

0
newtover

Es gibt einige Probleme mit den Streams mswcrt und io.

  1. Trick _setmode (_fileno (stdout), _O_U16TEXT); funktioniert nur für MS VC++ und nicht für MinGW-GCC. Außerdem kommt es manchmal zu Abstürzen, je nach Windows-Konfiguration.
  2. SetConsoleCP (65001) für UTF-8. Kann in vielen Multibyte-Zeichenszenarien fehlschlagen, ist jedoch für UTF-16LE immer in Ordnung
  3. Sie müssen die Vorschau-Konsolen-Codepage beim Beenden der Anwendung wiederherstellen.

Die Windows-Konsole unterstützt UNICODE mit den Funktionen ReadConsole und WriteConsole im UTF-16LE-Modus. Hintergrundeffekt - Piping funktioniert in diesem Fall nicht. Das heißt myapp.exe >> ret.log fügt die 0. Byte-Datei ret.log hinzu. Wenn Sie damit einverstanden sind, können Sie meine Bibliothek wie folgt ausprobieren.

const char* umessage = "Hello!\nПривет!\nПривіт!\nΧαιρετίσματα!\nHelló!\nHallå!\n";

...
#include <console.hpp>
#include <ios>
...

std::ostream& cout = io::console::out_stream();
cout << umessage
<< 1234567890ull << '\n'
<< 123456.78e+09 << '\n'
<< 12356.789e+10L << '\n'
<< std::hex << 0xCAFEBABE
<< std::endl;

Die Library konvertiert Ihr UTF-8 automatisch in UTF-16LE und schreibt es mit WriteConsole in die Konsole. Außerdem gibt es Fehler- und Eingabeströme. Ein weiterer Bibliotheksvorteil - Farben.

Link zur Beispiel-App: https://github.com/incoder1/IO/tree/master/examples/iostreams

Die Homepage der Bibliothek: https://github.com/incoder1/IO

Bildschirmfoto:

0
Victor Gubin

Zunächst einmal entschuldige ich, dass ich wahrscheinlich nicht über die erforderlichen Schriftarten verfügte, sodass ich sie noch nicht testen kann. 

Etwas sieht hier etwas faul aus

// the following is said to be working
SetConsoleOutputCP(CP_UTF8); // output is in UTF8
wchar_t s[] = L"èéøÞǽлљΣæča";
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
wprintf(L"%S", m); // <-- upper case %S in wprintf() is used for MultiByte/utf-8
                   //     lower case %s in wprintf() is used for WideChar
printf("%s", m); // <-- does this work as well? try it to verify my assumption

während

// the following is said to have problem
SetConsoleOutputCP(CP_UTF8);
utf8_locale = locale(old_locale,
                     new boost::program_options::detail::utf8_codecvt_facet());
wcout.imbue(utf8_locale);
wcout << L"¡Hola!" << endl; // <-- you are passing wide char.
// have you tried passing the multibyte equivalent by converting to utf8 first?
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, s, -1, NULL, 0, NULL, NULL);
char* m = new char[bufferSize]; 
WideCharToMultiByte(CP_UTF8, 0, s, -1, m, bufferSize, NULL, NULL);
cout << m << endl;

wie wäre es mit

// without setting locale to UTF8, you pass WideChars
wcout << L"¡Hola!" << endl;
// set locale to UTF8 and use cout
SetConsoleOutputCP(CP_UTF8);
cout << utf8_encoded_by_converting_using_WideCharToMultiByte << endl;
0
Afriza N. Arief

Standardcodierung am: 

  • Windows UTF-16. 
  • Linux UTF-8. 
  • MacOS UTF-8.

Meine Lösungsschritte enthalten Nullzeichen\0 (vermeiden Sie abgeschnitten). Ohne Funktionen für windows.h-Header zu verwenden: 

  1. Fügen Sie Makros hinzu, um die Plattform zu erkennen.
#if defined (_WIN32) 
#define WINDOWSLIB 1

#Elif defined (__Android__) || defined(Android)//Android
#define ANDROIDLIB 1

#Elif defined (__Apple__)//iOS, Mac OS
#define MACOSLIB 1

#Elif defined (__LINUX__) || defined(__gnu_linux__) || defined(__linux__)//_Ubuntu - Fedora - Centos - RedHat
#define LINUXLIB 1
#endif
  1. Erstellen Sie Konvertierungsfunktionen std :: w string in std :: string oder viceversa.
#include <locale>
#include <iostream>
#include <string>
#ifdef WINDOWSLIB
#include <Windows.h>
#endif

using namespace std::literals::string_literals;

// Convert std::wstring to std::string
std::string WidestringToString(const std::wstring& wstr, const std::string& locale)
{
    if (wstr.empty())
    {
        return std::string();
    }
    size_t pos;
    size_t begin = 0;
    std::string ret;
    size_t  size;
#ifdef WINDOWSLIB
    _locale_t lc = _create_locale(LC_ALL, locale.c_str());
    pos = wstr.find(static_cast<wchar_t>(0), begin);
    while (pos != std::wstring::npos && begin < wstr.length())
    {
        std::wstring segment = std::wstring(&wstr[begin], pos - begin);
        _wcstombs_s_l(&size, nullptr, 0, &segment[0], _TRUNCATE, lc);
        std::string converted = std::string(size, 0);
        _wcstombs_s_l(&size, &converted[0], size, &segment[0], _TRUNCATE, lc);
        ret.append(converted);
        begin = pos + 1;
        pos = wstr.find(static_cast<wchar_t>(0), begin);
    }
    if (begin <= wstr.length()) {
        std::wstring segment = std::wstring(&wstr[begin], wstr.length() - begin);
        _wcstombs_s_l(&size, nullptr, 0, &segment[0], _TRUNCATE, lc);
        std::string converted = std::string(size, 0);
        _wcstombs_s_l(&size, &converted[0], size, &segment[0], _TRUNCATE, lc);
        converted.resize(size - 1);
        ret.append(converted);
    }
    _free_locale(lc);
#Elif defined LINUXLIB
    std::string currentLocale = setlocale(LC_ALL, nullptr);
    setlocale(LC_ALL, locale.c_str());
    pos = wstr.find(static_cast<wchar_t>(0), begin);
    while (pos != std::wstring::npos && begin < wstr.length())
    {
        std::wstring segment = std::wstring(&wstr[begin], pos - begin);
        size = wcstombs(nullptr, segment.c_str(), 0);
        std::string converted = std::string(size, 0);
        wcstombs(&converted[0], segment.c_str(), converted.size());
        ret.append(converted);
        ret.append({ 0 });
        begin = pos + 1;
        pos = wstr.find(static_cast<wchar_t>(0), begin);
    }
    if (begin <= wstr.length()) {
        std::wstring segment = std::wstring(&wstr[begin], wstr.length() - begin);
        size = wcstombs(nullptr, segment.c_str(), 0);
        std::string converted = std::string(size, 0);
        wcstombs(&converted[0], segment.c_str(), converted.size());
        ret.append(converted);
    }
    setlocale(LC_ALL, currentLocale.c_str());
#Elif defined MACOSLIB
#endif

    return ret;
}

// Convert std::string to std::wstring
std::wstring StringToWideString(const std::string& str, const std::string& locale)
{
    if (str.empty())
    {
        return std::wstring();
    }

    size_t pos;
    size_t begin = 0;
    std::wstring ret;
    size_t  size;

#ifdef WINDOWSLIB
    _locale_t lc = _create_locale(LC_ALL, locale.c_str());
    pos = str.find(static_cast<char>(0), begin);
    while (pos != std::string::npos) {
        std::string segment = std::string(&str[begin], pos - begin);
        std::wstring converted = std::wstring(segment.size() + 1, 0);
        _mbstowcs_s_l(&size, &converted[0], converted.size(), &segment[0], _TRUNCATE, lc);
        converted.resize(size - 1);
        ret.append(converted);
        ret.append({ 0 });
        begin = pos + 1;
        pos = str.find(static_cast<char>(0), begin);
    }
    if (begin < str.length()) {
        std::string segment = std::string(&str[begin], str.length() - begin);
        std::wstring converted = std::wstring(segment.size() + 1, 0);
        _mbstowcs_s_l(&size, &converted[0], converted.size(), &segment[0], _TRUNCATE, lc);
        converted.resize(size - 1);
        ret.append(converted);
    }
    _free_locale(lc);
#Elif defined LINUXLIB
    std::string currentLocale = setlocale(LC_ALL, nullptr);
    setlocale(LC_ALL, locale.c_str());
    pos = str.find(static_cast<char>(0), begin);
    while (pos != std::string::npos) {
        std::string segment = std::string(&str[begin], pos - begin);
        std::wstring converted = std::wstring(segment.size(), 0);
        size = mbstowcs(&converted[0], &segment[0], converted.size());
        converted.resize(size);
        ret.append(converted);
        ret.append({ 0 });
        begin = pos + 1;
        pos = str.find(static_cast<char>(0), begin);
    }
    if (begin < str.length()) {
        std::string segment = std::string(&str[begin], str.length() - begin);
        std::wstring converted = std::wstring(segment.size(), 0);
        size = mbstowcs(&converted[0], &segment[0], converted.size());
        converted.resize(size);
        ret.append(converted);
    }
    setlocale(LC_ALL, currentLocale.c_str());
#Elif defined MACOSLIB
#endif

    return ret;
}
  1. Drucken Sie std :: string . Check RawString-Suffix .

Linux Code. Drucken Sie direkt std :: string mit std :: cout.
Wenn Sie std :: wstring haben.
1. Konvertieren Sie in std :: string.
2. Drucken Sie mit std :: cout. 

std::wstring x = L"\0\001日本ABC\0DE\0F\0G????\0"s;
std::string result = WidestringToString(x, "en_US.UTF-8");
std::cout << "RESULT=" << result << std::endl;
std::cout << "RESULT_SIZE=" << result.size() << std::endl;

Unter Windows, wenn Sie Unicode drucken müssen. Wir müssen WriteConsole verwenden, um Unicode-Zeichen aus std :: wstring oder std :: string zu drucken.

void WriteUnicodeLine(const std::string& s)
{
#ifdef WINDOWSLIB
    WriteUnicode(s);
    std::cout << std::endl;
#Elif defined LINUXLIB
    std::cout << s << std::endl;
#Elif defined MACOSLIB
#endif
}

void WriteUnicode(const std::string& s)
{

#ifdef WINDOWSLIB
    std::wstring unicode = Insane::String::Strings::StringToWideString(s);
    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), unicode.c_str(), static_cast<DWORD>(unicode.length()), nullptr, nullptr);
#Elif defined LINUXLIB
    std::cout << s;
#Elif defined MACOSLIB
#endif


}

void WriteUnicodeLineW(const std::wstring& ws)
{

#ifdef WINDOWSLIB
    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), ws.c_str(), static_cast<DWORD>(ws.length()), nullptr, nullptr);
    std::cout << std::endl;
#Elif defined LINUXLIB
    std::cout << String::Strings::WidestringToString(ws)<<std::endl;
#Elif defined MACOSLIB
#endif


}

void WriteUnicodeW(const std::wstring& ws)
{

#ifdef WINDOWSLIB
    WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), ws.c_str(), static_cast<DWORD>(ws.length()), nullptr, nullptr);
#Elif defined LINUXLIB
    std::cout << String::Strings::WidestringToString(ws);
#Elif defined MACOSLIB
#endif

}

Windows-Code. Verwendung der Funktion WriteLineUnicode oder WriteUnicode. Der gleiche Code kann für Linux verwendet werden. 

std::wstring x = L"\0\001日本ABC\0DE\0F\0G????\0"s;
std::string result = WidestringToString(x, "en_US.UTF-8");
WriteLineUnicode(u8"RESULT" + result);
WriteLineUnicode(u8"RESULT_SIZE" + std::to_string(result.size()));

Endlich unter Windows. Sie benötigen eine umfassende und vollständige Unterstützung für Unicode-Zeichen in der Konsole. Ich empfehle ConEmu und als Standardterminal unter Windows

Testen Sie Microsoft Visual Studio und Jetbrains Clion.

  • Getestet auf Microsoft Visual Studio 2017 mit VC++; std = c ++ 17. (Windows-Projekt)
  • Getestet auf Microsoft Visual Studio 2017 mit g ++; std = c ++ 17. (Linux-Projekt)
  • Getestet auf Jetbrains Clion 2018.3 mit g ++; std = c ++ 17. (Linux Toolchain/Remote)

QA

Q. Warum verwenden Sie keine <codecvt>-Header-Funktionen und -Klassen ?.
A. Veraltet Entfernte oder veraltete Funktionen Unmögliches Erstellen von VC++, aber keine Probleme mit g ++. Ich bevorzuge 0 Warnungen und Kopfschmerzen.

Q. wstring unter Windows ist interchan.
A. Veraltet Entfernte oder veraltete Funktionen Unmögliches Erstellen von VC++, aber keine Probleme mit g ++. Ich bevorzuge 0 Warnungen und Kopfschmerzen. 

Q. std :: wstring ist plattformübergreifend?
A. Nein. Std :: wstring verwendet wchar_t-Elemente. Unter Windows ist die Größe von wchar_t 2 Byte, jedes Zeichen wird in UTF-16-Einheiten gespeichert. Ist das Zeichen größer als U + FFFF, wird das Zeichen in zwei UTF-16-Einheiten (2 wchar_t-Elementen) dargestellt, die als Ersatzpaare bezeichnet werden. Unter Linux ist die Größe von wchar_t 4 Byte, und jedes Zeichen wird in einem Element wchar_t gespeichert. Es werden keine Ersatzpaare benötigt. Überprüfen Sie Standard-Datentypen unter UNIX, Linux und Windows .

Q. std :: string ist plattformübergreifend?
A. Ja. std :: string verwendet char-Elemente. Char-Typ garantiert, dass die Byte-Größe in allen Compilern gleich ist. Zeichentypgröße ist 1 Byte. Überprüfen Sie Standard-Datentypen unter UNIX, Linux und Windows .

0
Joma

Ich glaube nicht, dass es eine einfache Antwort gibt. Schauen Sie sich die Console Code Pages und SetConsoleCP Function an Es scheint, dass Sie eine geeignete Codepage für den Zeichensatz einrichten müssen, den Sie ausgeben möchten.

0
call me Steve