Wie konvertiert man wstring in string?

Lesezeit: 21 Minuten

Wie konvertiert man wstring in string
BЈовић

Die Frage ist, wie man wstring in String umwandelt.

Ich habe das nächste Beispiel:

#include <string>
#include <iostream>

int main()
{
    std::wstring ws = L"Hello";
    std::string s( ws.begin(), ws.end() );

  //std::cout <<"std::string =     "<<s<<std::endl;
    std::wcout<<"std::wstring =    "<<ws<<std::endl;
    std::cout <<"std::string =     "<<s<<std::endl;
}

Die Ausgabe mit auskommentierter Zeile lautet:

std::string =     Hello
std::wstring =    Hello
std::string =     Hello

aber ohne ist nur :

std::wstring =    Hello

Ist an dem Beispiel etwas falsch? Kann ich die Konvertierung wie oben durchführen?

BEARBEITEN

Neues Beispiel (unter Berücksichtigung einiger Antworten) ist

#include <string>
#include <iostream>
#include <sstream>
#include <locale>

int main()
{
    setlocale(LC_CTYPE, "");

    const std::wstring ws = L"Hello";
    const std::string s( ws.begin(), ws.end() );

    std::cout<<"std::string =     "<<s<<std::endl;
    std::wcout<<"std::wstring =    "<<ws<<std::endl;

    std::stringstream ss;
    ss << ws.c_str();
    std::cout<<"std::stringstream =     "<<ss.str()<<std::endl;
}

Die Ausgabe ist:

std::string =     Hello
std::wstring =    Hello
std::stringstream =     0x860283c

Daher kann der Stringstream nicht verwendet werden, um wstring in einen String umzuwandeln.

  • Wie können Sie diese Frage stellen, ohne auch die Kodierungen anzugeben?

    – David Heffernan

    26. Januar 2011 um 12:15 Uhr

  • @tenfour: Warum verwenden std::wstring überhaupt? stackoverflow.com/questions/1049947/…

    – dalle

    26. Januar 2011 um 13:14 Uhr

  • @dalle Wenn Sie Daten haben, die bereits mit UTF-16 codiert sind, ist es etwas umstritten, ob UTF-16 als schädlich angesehen wird oder nicht. Und für das, was es wert ist, denke ich nicht, dass irgendeine Transformationsform schädlich ist; Was schädlich ist, ist, dass Leute denken, sie verstehen Unicode, obwohl sie es in Wirklichkeit nicht tun.

    – David Heffernan

    26. Januar 2011 um 13:17 Uhr


  • Muss es eine plattformübergreifende Lösung sein?

    – ali_bahoo

    26. Januar 2011 um 13:18 Uhr

  • @dalle C++ Standard erwähnt utf in keiner Weise (utf-8 oder utf-16). Haben Sie einen Link, in dem steht, warum utf-16 nicht mit wstring codiert werden kann?

    – BЈовић

    26. Januar 2011 um 14:08 Uhr

Wie konvertiert man wstring in string
dk123

Wie Cubbi in einem der Kommentare betonte, std::wstring_convert (C++11) bietet eine nette einfache Lösung (Sie müssen #include <locale> und <codecvt>):

std::wstring string_to_convert;

//setup converter
using convert_type = std::codecvt_utf8<wchar_t>;
std::wstring_convert<convert_type, wchar_t> converter;

//use converter (.to_bytes: wstr->str, .from_bytes: str->wstr)
std::string converted_str = converter.to_bytes( string_to_convert );

Ich benutzte eine Kombination aus wcstombs und langwierige Zuweisung / Freigabe von Speicher, bevor ich darauf stieß.

http://en.cppreference.com/w/cpp/locale/wstring_convert

aktualisieren (2013.11.28)

Einzeiler können so angegeben werden (Danke Guss für Ihren Kommentar):

std::wstring str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().from_bytes("some string");

Wrapper-Funktionen können wie folgt angegeben werden: (Danke ArmanSchwarz für Ihren Kommentar)

std::wstring s2ws(const std::string& str)
{
    using convert_typeX = std::codecvt_utf8<wchar_t>;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.from_bytes(str);
}

std::string ws2s(const std::wstring& wstr)
{
    using convert_typeX = std::codecvt_utf8<wchar_t>;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.to_bytes(wstr);
}

Hinweis: Es gibt einige Kontroversen darüber, ob string/wstring sollten als Referenzen oder als Literale (aufgrund von C++11- und Compiler-Updates) an Funktionen übergeben werden. Ich überlasse die Entscheidung der Person, die die Implementierung durchführt, aber es ist wissenswert.

Hinweis: Ich verwende std::codecvt_utf8 im obigen Code, aber wenn Sie nicht UTF-8 verwenden, müssen Sie dies in die entsprechende Codierung ändern, die Sie verwenden:

http://en.cppreference.com/w/cpp/header/codecvt

  • Bitte +1: Dies ist die offizielle C++-Standardmethode zur Konvertierung von Zeichenfolgen. Sie können auch from_bytes verwenden, um den anderen Weg zu konvertieren. Da ich persönlich Einzeiler mag, hier meine Version: std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");

    – Guss

    11. November 2013 um 12:59 Uhr


  • Sieht aus wie de.cppreference.com/w/cpp/header/codecvt ist ab g++ 4.8.2 nicht verfügbar. Die beiden Methoden s2ws und ws2s funktionieren derzeit nicht unter Linux

    – Begui

    10. September 2014 um 11:34 Uhr

  • Es sieht so aus, als ob dies veraltet ist (stackoverflow.com/a/42946556/211176). Mein Compiler gibt Fehler aus, wenn ich versuche, diesen Code auszuführen

    – adam_0

    14. Februar 2018 um 19:53 Uhr

  • In C++17 veraltet… de.cppreference.com/w/cpp/locale/wstring_convert en.cppreference.com/w/cpp/locale/codecvt_utf8

    – Joma

    26. September 2018 um 17:00 Uhr

  • Für alle, die sich Sorgen um C++17 und weitere Kompatibilität (aufgrund von Verwerfungen) machen, siehe: stackoverflow.com/a/18597384/6205379

    –Timo

    20. März 2019 um 14:32 Uhr

1646958015 986 Wie konvertiert man wstring in string
namar0x0309

Eine ältere Lösung von: http://forums.devshed.com/c-programming-42/wstring-to-string-444006.html

std::wstring wide( L"Wide" ); 
std::string str( wide.begin(), wide.end() );

// Will print no problemo!
std::cout << str << std::endl;

Aktualisierung (2021): Zumindest bei neueren Versionen von MSVC kann dies jedoch eine wchar_t zu char Kürzungswarnung. Die Warnung kann mit abgestellt werden std::transform stattdessen mit expliziter Konvertierung in der Transformationsfunktion, zB:

std::wstring wide( L"Wide" );

std::string str;
std::transform(wide.begin(), wide.end(), std::back_inserter(str), [] (wchar_t c) {
    return (char)c;
});

Oder wenn Sie es vorziehen, vorab zuzuweisen und nicht zu verwenden back_inserter:

std::string str(wide.length(), 0);
std::transform(wide.begin(), wide.end(), str.begin(), [] (wchar_t c) {
    return (char)c;
});

Siehe Beispiel zu verschiedenen Compilern Hier.


In acht nehmen dass es gibt Nein Zeichensatzkonvertierung findet hier überhaupt nicht statt. Was dies tut, ist einfach, jede Iteration zuzuweisen wchar_t zu einem char – eine abschneidende Konvertierung. Es verwendet die std::string c’tor:

template< class InputIt >
basic_string( InputIt first, InputIt last,
              const Allocator& alloc = Allocator() );

Wie in den Kommentaren angegeben:

Die Werte 0-127 sind in praktisch jeder Codierung identisch, sodass das Abschneiden von Werten, die alle kleiner als 127 sind, denselben Text ergibt. Geben Sie ein chinesisches Schriftzeichen ein und Sie werden den Fehler sehen.

Die Werte 128-255 der Windows-Codepage 1252 (die englische Windows-Standardeinstellung) und die Werte 128-255 von Unicode sind größtenteils gleich. Wenn das also die Codepage ist, die Sie verwenden, sollten die meisten dieser Zeichen auf die richtigen Werte gekürzt werden. (Ich habe total erwartet, dass á und õ funktionieren, ich weiß, dass unser Code bei der Arbeit darauf für é angewiesen ist, was ich bald beheben werde.)

Und beachten Sie, dass Codepunkte im Bereich liegen 0x80 - 0x9F in Win1252 Wille nicht Arbeit. Das beinhaltet , œ, ž, Ÿ

  • Seltsamerweise funktioniert dies auf Visual Studio 10. Was ist los? Dies sollte eine abgeschnittene Zuweisung von wchar_t nach char für alle Elemente des ursprünglichen Strings bewirken.

    – Pedro Lamarão

    4. Januar 2013 um 17:41 Uhr

  • …wenn es um nicht-lateinische Zeichen geht.

    – JavaRunner

    31. Mai 2013 um 21:14 Uhr

  • @PedroLamarão: Die Werte 0-127 sind in praktisch jeder Codierung identisch, sodass das Abschneiden von Werten, die alle kleiner als 127 sind, denselben Text ergibt. Geben Sie ein chinesisches Schriftzeichen ein und Sie werden den Fehler sehen.

    – Muhende Ente

    4. September 2013 um 20:20 Uhr

  • @PedroLamarão: Die Werte 128-255 der Windows-Codepage 1252 (der englische Windows-Standard) und die Werte 128-255 von Unicode sind meistens das gleiche, also wenn das die Codepage ist, die Sie verwenden die meisten dieser Zeichen sollten auf die richtigen Werte gekürzt werden. (Ich habe total erwartet, dass á und õ funktionieren, ich weiß, dass unser Code bei der Arbeit darauf für é angewiesen ist, was ich bald beheben werde.)

    – Muhende Ente

    5. September 2013 um 16:30 Uhr


  • Das hat bei mir funktioniert, bis ich auf MSVC 2019 und v142-Toolset aktualisiert habe – jetzt scheißt es mit einer Warnung aus (die ich immer als Fehler behandle): warning C4244: 'argument': conversion from 'const wchar_t' to 'const _Elem', possible loss of data

    – YePhIcK

    14. April 2019 um 13:26 Uhr

Wie konvertiert man wstring in string
Philipp

Hier ist eine ausgearbeitete Lösung basierend auf den anderen Vorschlägen:

#include <string>
#include <iostream>
#include <clocale>
#include <locale>
#include <vector>

int main() {
  std::setlocale(LC_ALL, "");
  const std::wstring ws = L"ħëłlö";
  const std::locale locale("");
  typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;
  const converter_type& converter = std::use_facet<converter_type>(locale);
  std::vector<char> to(ws.length() * converter.max_length());
  std::mbstate_t state;
  const wchar_t* from_next;
  char* to_next;
  const converter_type::result result = converter.out(state, ws.data(), ws.data() + ws.length(), from_next, &to[0], &to[0] + to.size(), to_next);
  if (result == converter_type::ok or result == converter_type::noconv) {
    const std::string s(&to[0], to_next);
    std::cout <<"std::string =     "<<s<<std::endl;
  }
}

Dies funktioniert normalerweise für Linux, führt jedoch zu Problemen unter Windows.

  • @Phillip: Welcher Teil des Codes hängt vom c-locale ab? ist der std::setlocale(LC_ALL, ""); wirklich nötig?

    – Smerlin

    26. Januar 2011 um 14:44 Uhr

  • verwenden std::wcout.imbue(locale) sollte es auch tun, und es hat den Vorteil, dass es keinen globalen Zustand ändert.

    – Smerlin

    26. Januar 2011 um 15:22 Uhr


  • Die std::wstring_convert von C++11 wickelt einen Großteil dieses Rauschens ein.

    – Kubbi

    27. September 2011 um 19:34 Uhr

  • @Philipp, was meinst du mit “wird Probleme unter Windows verursachen”? Welche Art von Problemen?

    – Gili

    23. November 2011 um 21:45 Uhr


  • Der obige Code gibt (wie kopiert) mir ein *** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 *** auf Linux 64-Bit (gcc 4.7.3). Hat das noch jemand erlebt?

    – Hogliux

    10. November 2013 um 12:22 Uhr


1646803210 649 Wie kann ich die Konsole loschen
Joma

Standardkodierung an:

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

Meine Lösungsschritte enthalten Nullzeichen \0 (vermeide abgeschnitten). Ohne Funktionen im Header windows.h zu verwenden:

  1. Fügen Sie Makros hinzu, um die Plattform zu erkennen.
    Windows/Linux und andere
  1. Erstellen Sie eine Funktion, um std::wstring in std::string zu konvertieren und std::string in std::wstring umzuwandeln
  1. Funktion zum Drucken erstellen
  1. Gibt std::string/ std::wstring aus

Überprüfen RawString-Literale. Raw-String-Suffix.

Linux-Code. Direkt drucken std::string verwenden std::coutStandardcodierung unter Linux ist UTF-8, keine zusätzlichen Funktionen erforderlich.

Unter Windows, wenn Sie Unicode drucken müssen. Wir können benutzen WriteConsole zum Drucken von Unicode-Zeichen aus std::wstring.

Endlich unter Windows. Sie benötigen eine leistungsstarke und vollständige Ansichtsunterstützung für Unicode-Zeichen in der Konsole.
Ich empfehle Windows-Terminal

Qualitätssicherung

  • Getestet auf Microsoft Visual Studio 2019 mit VC++; std=c++17. (Windows-Projekt)
  • Getestet auf repl.it mit dem Clang-Compiler; std=c++17.

Q. Warum Sie nicht verwenden <codecvt> Header-Funktionen und Klassen?.
A. Missbilligen Entfernte oder veraltete Funktionen unmöglicher Aufbau auf VC++, aber keine Probleme auf g++. Ich bevorzuge 0 Warnungen und Kopfschmerzen.

Q. std ::wstring ist plattformübergreifend?
A. Nein. std::wstring verwendet wchar_t-Elemente. Unter Windows beträgt die wchar_t-Größe 2 Bytes, jedes Zeichen wird in UTF-16-Einheiten gespeichert. Wenn das Zeichen größer als U+FFFF ist, wird das Zeichen in zwei UTF-16-Einheiten (2 wchar_t-Elementen) dargestellt, die als Ersatzpaare bezeichnet werden. Unter Linux beträgt die wchar_t-Größe 4 Bytes, jedes Zeichen wird in einem wchar_t-Element gespeichert, es werden keine Ersatzpaare benötigt. Überprüfen Standarddatentypen unter UNIX, Linux und Windows1.

Q. std ::string ist plattformübergreifend?
A. Jawohl. std::string verwendet char-Elemente. char-Typ wird garantiert, dass die gleiche Bytegröße in den meisten Compilern ist. Die Größe des Zeichentyps beträgt 1 Byte. Überprüfen Standarddatentypen unter UNIX, Linux und Windows1.

Vollständiger Beispielcode


#include <iostream>
#include <set>
#include <string>
#include <locale>

// WINDOWS
#if (_WIN32)
#include <Windows.h>
#include <conio.h>
#define WINDOWS_PLATFORM 1
#define DLLCALL STDCALL
#define DLLIMPORT _declspec(dllimport)
#define DLLEXPORT _declspec(dllexport)
#define DLLPRIVATE
#define NOMINMAX

//EMSCRIPTEN
#elif defined(__EMSCRIPTEN__)
#include <emscripten/emscripten.h>
#include <emscripten/bind.h>
#include <unistd.h>
#include <termios.h>
#define EMSCRIPTEN_PLATFORM 1
#define DLLCALL
#define DLLIMPORT
#define DLLEXPORT __attribute__((visibility("default")))
#define DLLPRIVATE __attribute__((visibility("hidden")))

// LINUX - Ubuntu, Fedora, , Centos, Debian, RedHat
#elif (__LINUX__ || __gnu_linux__ || __linux__ || __linux || linux)
#define LINUX_PLATFORM 1
#include <unistd.h>
#include <termios.h>
#define DLLCALL CDECL
#define DLLIMPORT
#define DLLEXPORT __attribute__((visibility("default")))
#define DLLPRIVATE __attribute__((visibility("hidden")))
#define CoTaskMemAlloc(p) malloc(p)
#define CoTaskMemFree(p) free(p)

//ANDROID
#elif (__ANDROID__ || ANDROID)
#define ANDROID_PLATFORM 1
#define DLLCALL
#define DLLIMPORT
#define DLLEXPORT __attribute__((visibility("default")))
#define DLLPRIVATE __attribute__((visibility("hidden")))

//MACOS
#elif defined(__APPLE__)
#include <unistd.h>
#include <termios.h>
#define DLLCALL
#define DLLIMPORT
#define DLLEXPORT __attribute__((visibility("default")))
#define DLLPRIVATE __attribute__((visibility("hidden")))
#include "TargetConditionals.h"
#if TARGET_OS_IPHONE && TARGET_IPHONE_SIMULATOR
#define IOS_SIMULATOR_PLATFORM 1
#elif TARGET_OS_IPHONE
#define IOS_PLATFORM 1
#elif TARGET_OS_MAC
#define MACOS_PLATFORM 1
#else

#endif

#endif



typedef std::string String;
typedef std::wstring WString;

#define EMPTY_STRING u8""s
#define EMPTY_WSTRING L""s

using namespace std::literals::string_literals;

class Strings
{
public:
    static String WideStringToString(const WString& wstr)
    {
        if (wstr.empty())
        {
            return String();
        }
        size_t pos;
        size_t begin = 0;
        String ret;

#if WINDOWS_PLATFORM
        int size;
        pos = wstr.find(static_cast<wchar_t>(0), begin);
        while (pos != WString::npos && begin < wstr.length())
        {
            WString segment = WString(&wstr[begin], pos - begin);
            size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), NULL, 0, NULL, NULL);
            String converted = String(size, 0);
            WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), &converted[0], converted.size(), NULL, NULL);
            ret.append(converted);
            ret.append({ 0 });
            begin = pos + 1;
            pos = wstr.find(static_cast<wchar_t>(0), begin);
        }
        if (begin <= wstr.length())
        {
            WString segment = WString(&wstr[begin], wstr.length() - begin);
            size = WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), NULL, 0, NULL, NULL);
            String converted = String(size, 0);
            WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, &segment[0], segment.size(), &converted[0], converted.size(), NULL, NULL);
            ret.append(converted);
        }
#elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
        size_t size;
        pos = wstr.find(static_cast<wchar_t>(0), begin);
        while (pos != WString::npos && begin < wstr.length())
        {
            WString segment = WString(&wstr[begin], pos - begin);
            size = wcstombs(nullptr, segment.c_str(), 0);
            String converted = 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())
        {
            WString segment = WString(&wstr[begin], wstr.length() - begin);
            size = wcstombs(nullptr, segment.c_str(), 0);
            String converted = String(size, 0);
            wcstombs(&converted[0], segment.c_str(), converted.size());
            ret.append(converted);
        }
#else
        static_assert(false, "Unknown Platform");
#endif
        return ret;
    }

    static WString StringToWideString(const String& str)
    {
        if (str.empty())
        {
            return WString();
        }

        size_t pos;
        size_t begin = 0;
        WString ret;
#ifdef WINDOWS_PLATFORM
        int size = 0;
        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);
            size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, &segment[0], segment.size(), &converted[0], converted.length());
            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() + 1, 0);
            size = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, segment.c_str(), segment.size(), &converted[0], converted.length());
            converted.resize(size);
            ret.append(converted);
        }

#elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
        size_t size;
        pos = str.find(static_cast<char>(0), begin);
        while (pos != String::npos)
        {
            String segment = String(&str[begin], pos - begin);
            WString converted = 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())
        {
            String segment = String(&str[begin], str.length() - begin);
            WString converted = WString(segment.size(), 0);
            size = mbstowcs(&converted[0], &segment[0], converted.size());
            converted.resize(size);
            ret.append(converted);
        }
#else
        static_assert(false, "Unknown Platform");
#endif
        return ret;
    }
};

enum class ConsoleTextStyle
{
    DEFAULT = 0,
    BOLD = 1,
    FAINT = 2,
    ITALIC = 3,
    UNDERLINE = 4,
    SLOW_BLINK = 5,
    RAPID_BLINK = 6,
    REVERSE = 7,
};

enum class ConsoleForeground
{
    DEFAULT = 39,
    BLACK = 30,
    DARK_RED = 31,
    DARK_GREEN = 32,
    DARK_YELLOW = 33,
    DARK_BLUE = 34,
    DARK_MAGENTA = 35,
    DARK_CYAN = 36,
    GRAY = 37,
    DARK_GRAY = 90,
    RED = 91,
    GREEN = 92,
    YELLOW = 93,
    BLUE = 94,
    MAGENTA = 95,
    CYAN = 96,
    WHITE = 97
};

enum class ConsoleBackground
{
    DEFAULT = 49,
    BLACK = 40,
    DARK_RED = 41,
    DARK_GREEN = 42,
    DARK_YELLOW = 43,
    DARK_BLUE = 44,
    DARK_MAGENTA = 45,
    DARK_CYAN = 46,
    GRAY = 47,
    DARK_GRAY = 100,
    RED = 101,
    GREEN = 102,
    YELLOW = 103,
    BLUE = 104,
    MAGENTA = 105,
    CYAN = 106,
    WHITE = 107
};

class Console
{
private:
    static void EnableVirtualTermimalProcessing()
    {
#if defined WINDOWS_PLATFORM
        HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
        DWORD dwMode = 0;
        GetConsoleMode(hOut, &dwMode);
        if (!(dwMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING))
        {
            dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
            SetConsoleMode(hOut, dwMode);
        }
#endif
    }

    static void ResetTerminalFormat()
    {
        std::cout << u8"\033[0m";
    }

    static void SetVirtualTerminalFormat(ConsoleForeground foreground, ConsoleBackground background, std::set<ConsoleTextStyle> styles)
    {
        String format = u8"\033[";
        format.append(std::to_string(static_cast<int>(foreground)));
        format.append(u8";");
        format.append(std::to_string(static_cast<int>(background)));
        if (styles.size() > 0)
        {
            for (auto it = styles.begin(); it != styles.end(); ++it)
            {
                format.append(u8";");
                format.append(std::to_string(static_cast<int>(*it)));
            }
        }
        format.append(u8"m");
        std::cout << format;
    }
public:
    static void Clear()
    {

#ifdef WINDOWS_PLATFORM
        std::system(u8"cls");
#elif LINUX_PLATFORM || defined MACOS_PLATFORM
        std::system(u8"clear");
#elif EMSCRIPTEN_PLATFORM
        emscripten::val::global()["console"].call<void>(u8"clear");
#else
        static_assert(false, "Unknown Platform");
#endif
    }

    static void Write(const String& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
    {
#ifndef EMSCRIPTEN_PLATFORM
        EnableVirtualTermimalProcessing();
        SetVirtualTerminalFormat(foreground, background, styles);
#endif
        String str = s;
#ifdef WINDOWS_PLATFORM
        WString unicode = Strings::StringToWideString(str);
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), unicode.c_str(), static_cast<DWORD>(unicode.length()), nullptr, nullptr);
#elif defined LINUX_PLATFORM || defined MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
        std::cout << str;
#else
        static_assert(false, "Unknown Platform");
#endif

#ifndef EMSCRIPTEN_PLATFORM
        ResetTerminalFormat();
#endif
    }

    static void WriteLine(const String& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
    {
        Write(s, foreground, background, styles);
        std::cout << std::endl;
    }

    static void Write(const WString& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
    {
#ifndef EMSCRIPTEN_PLATFORM
        EnableVirtualTermimalProcessing();
        SetVirtualTerminalFormat(foreground, background, styles);
#endif
        WString str = s;

#ifdef WINDOWS_PLATFORM
        WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), str.c_str(), static_cast<DWORD>(str.length()), nullptr, nullptr);
#elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
        std::cout << Strings::WideStringToString(str);
#else
        static_assert(false, "Unknown Platform");
#endif

#ifndef EMSCRIPTEN_PLATFORM
        ResetTerminalFormat();
#endif
    }

    static void WriteLine(const WString& s, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
    {
        Write(s, foreground, background, styles);
        std::cout << std::endl;
    }

    static void WriteLine()
    {
        std::cout << std::endl;
    }

    static void Pause()
    {
        char c;
        do
        {
            c = getchar();
            std::cout << "Press Key " << std::endl;
        } while (c != 64);
        std::cout << "KeyPressed" << std::endl;
    }

    static int PauseAny(bool printWhenPressed = false, ConsoleForeground foreground = ConsoleForeground::DEFAULT, ConsoleBackground background = ConsoleBackground::DEFAULT, std::set<ConsoleTextStyle> styles = {})
    {
        int ch;
#ifdef WINDOWS_PLATFORM
        ch = _getch();
#elif LINUX_PLATFORM || MACOS_PLATFORM || EMSCRIPTEN_PLATFORM
        struct termios oldt, newt;
        tcgetattr(STDIN_FILENO, &oldt);
        newt = oldt;
        newt.c_lflag &= ~(ICANON | ECHO);
        tcsetattr(STDIN_FILENO, TCSANOW, &newt);
        ch = getchar();
        tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
#else
        static_assert(false, "Unknown Platform");
#endif
        if (printWhenPressed)
        {
            Console::Write(String(1, ch), foreground, background, styles);
        }
        return ch;
    }
};



int main()
{
    std::locale::global(std::locale(u8"en_US.UTF8"));
    auto str = u8"🐶\0Hello\0🐶123456789也不是可运行的程序123456789日本"s;//
    WString wstr = L"🐶\0Hello\0🐶123456789也不是可运行的程序123456789日本"s;
    WString wstrResult = Strings::StringToWideString(str);
    String strResult = Strings::WideStringToString(wstr);
    bool equals1 = wstr == wstrResult;
    bool equals2 = str == strResult;

    Console::WriteLine(u8"█ Converted Strings printed with Console::WriteLine"s, ConsoleForeground::GREEN);
    Console::WriteLine(wstrResult, ConsoleForeground::BLUE);//Printed OK on Windows/Linux.
    Console::WriteLine(strResult, ConsoleForeground::BLUE);//Printed OK on Windows/Linux.
    
    Console::WriteLine(u8"█ Converted Strings printed with std::cout/std::wcout"s, ConsoleForeground::GREEN);
    std::cout << strResult << std::endl;//Printed OK on Linux. BAD on Windows.
    std::wcout << wstrResult << std::endl; //Printed BAD on Windows/Linux.
    Console::WriteLine();
    Console::WriteLine(u8"Press any key to exit"s, ConsoleForeground::DARK_GRAY);
    Console::PauseAny();

}

Sie können diesen Code nicht testen https://repl.it/@JomaCorpFX/StringToWideStringToString#main.cpp


**Screenshots**

Verwenden von Windows-Terminal
Windows-Terminal

Verwenden von cmd/powershell
Geben Sie hier die Bildbeschreibung ein

Repl.it-Erfassung
Geben Sie hier die Bildbeschreibung ein

Anstatt das Gebietsschema und all das ausgefallene Zeug einzufügen, wenn Sie wissen, dass Ihre Zeichenfolge für FACT konvertierbar ist, tun Sie dies einfach:

#include <iostream>
#include <string>

using namespace std;

int main()
{
  wstring w(L"bla");
  string result;
  for(char x : w)
    result += x;

  cout << result << '\n';
}

Live-Beispiel Hier

  • +1, weil es eine einfache Lösung ist, die für einige Szenarien funktioniert (für eine lockere Definition von “funktioniert”, könnte ich hinzufügen).

    – Rabe

    14. August 2012 um 9:43 Uhr

  • Fast dasselbe wie die Lösung von namar0x0309, die IMHO viel eleganter ist. Aber das bin nur ich.

    – Onitake

    17. Juni 2013 um 13:57 Uhr

  • Ich habe Ihren Code so aufpoliert, dass er tatsächlich mit minimalen Änderungen funktioniert 😉

    – rubenvb

    22. August 2013 um 8:05 Uhr

  • -1 Wenn Sie einen wstring haben, haben Sie es wahrscheinlich mit Multibyte-Zeichen zu tun. Wenn Sie wissen könnten, dass der String trivial konvertierbar ist, würden Sie überhaupt nicht mit einem wstring umgehen. Wahrscheinlicher ist, dass Sie es mit einer anderen Bibliothek zu tun haben, die von Ihnen erwartet, dass Sie wstring richtig handhaben. Das Abschneiden der wchars schreit nur nach einem später schwer nachzuvollziehenden Fehler. Außerdem sollten Sie “string result( w.begin(), w.end() );” wenn Sie es tun würden, um eine Schleife zu vermeiden, die viele Neuzuweisungen auslösen könnte.

    – Kien

    22. Mai 2014 um 19:35 Uhr

  • @Kian, schlicht und einfach und perfekt für einige begrenzte Anwendungsfälle.

    – Devolus

    14. Februar 2021 um 16:17 Uhr

1646958018 451 Wie konvertiert man wstring in string
Christoph Creutzig

Ich glaube, der offizielle Weg ist noch zu gehen codecvt Facetten (Sie brauchen eine Art länderspezifische Übersetzung), wie in

resultCode = use_facet<codecvt<char, wchar_t, ConversionState> >(locale).
  in(stateVar, scratchbuffer, scratchbufferEnd, from, to, toLimit, curPtr);

oder so ähnlich, ich habe keinen funktionierenden Code herumliegen. Aber ich bin mir nicht sicher, wie viele Menschen heutzutage diese Maschinen benutzen und wie viele einfach nach Hinweisen auf Erinnerungen fragen und die Intensivstation oder eine andere Bibliothek die blutigen Details erledigen lassen.

  • +1, weil es eine einfache Lösung ist, die für einige Szenarien funktioniert (für eine lockere Definition von “funktioniert”, könnte ich hinzufügen).

    – Rabe

    14. August 2012 um 9:43 Uhr

  • Fast dasselbe wie die Lösung von namar0x0309, die IMHO viel eleganter ist. Aber das bin nur ich.

    – Onitake

    17. Juni 2013 um 13:57 Uhr

  • Ich habe Ihren Code so aufpoliert, dass er tatsächlich mit minimalen Änderungen funktioniert 😉

    – rubenvb

    22. August 2013 um 8:05 Uhr

  • -1 Wenn Sie einen wstring haben, haben Sie es wahrscheinlich mit Multibyte-Zeichen zu tun. Wenn Sie wissen könnten, dass der String trivial konvertierbar ist, würden Sie überhaupt nicht mit einem wstring umgehen. Wahrscheinlicher ist, dass Sie es mit einer anderen Bibliothek zu tun haben, die von Ihnen erwartet, dass Sie wstring richtig handhaben. Das Abschneiden der wchars schreit nur nach einem später schwer nachzuvollziehenden Fehler. Außerdem sollten Sie “string result( w.begin(), w.end() );” wenn Sie es tun würden, um eine Schleife zu vermeiden, die viele Neuzuweisungen auslösen könnte.

    – Kien

    22. Mai 2014 um 19:35 Uhr

  • @Kian, schlicht und einfach und perfekt für einige begrenzte Anwendungsfälle.

    – Devolus

    14. Februar 2021 um 16:17 Uhr

1646958018 152 Wie konvertiert man wstring in string
Gemeinschaft

Es gibt zwei Probleme mit dem Code:

  1. Die Umstellung im const std::string s( ws.begin(), ws.end() ); ist nicht erforderlich, um die breiten Zeichen ihrem schmalen Gegenstück korrekt zuzuordnen. Höchstwahrscheinlich wird jedes breite Zeichen nur typisiert char.
    Die Lösung für dieses Problem ist bereits in der Antwort von kem angegeben und beinhaltet die narrow Funktion des Gebietsschemas ctype Facette.

  2. Sie schreiben die Ausgabe an beide std::cout und std::wcout im selben Programm. Beide cout und wcout sind demselben Stream zugeordnet (stdout) und die Ergebnisse der Verwendung desselben Streams sowohl als byteorientierter Stream (als cout tut) und einen breit orientierten Strom (wie wcout tut) sind nicht definiert.
    Die beste Option besteht darin, das Mischen schmaler und breiter Ausgabe mit demselben (unterliegenden) Stream zu vermeiden. Zum stdout/cout/wcoutkönnen Sie versuchen, die Ausrichtung zu ändern stdout beim Umschalten zwischen breiter und schmaler Ausgabe (oder umgekehrt):

    #include <iostream>
    #include <stdio.h>
    #include <wchar.h>
    
    int main() {
        std::cout << "narrow" << std::endl;
        fwide(stdout, 1); // switch to wide
        std::wcout << L"wide" << std::endl;
        fwide(stdout, -1); // switch to narrow
        std::cout << "narrow" << std::endl;
        fwide(stdout, 1); // switch to wide
        std::wcout << L"wide" << std::endl;
    }
    

  • Ja, das behebt das Problem bei der Verwendung von cout und wcout.

    – BЈовић

    26. Januar 2011 um 16:21 Uhr

989370cookie-checkWie konvertiert man wstring in string?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy