34 Stimmen

Wie konvertiert man UTF-8 std::string in UTF-16 std::wstring?

Wenn ich eine UTF-8 std::string wie konvertiere ich sie in UTF-16 std::wstring ? Eigentlich möchte ich zwei persische Wörter vergleichen.

1 Stimmen

0 Stimmen

54voto

Yuchen Punkte 27087

So machen Sie es mit C++11 :

std::string str = "your string in utf8";
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>> converter;
std::wstring wstr = converter.from_bytes(str);

Und das sind die Kopfzeilen, die Sie brauchen:

#include <iostream>
#include <string>
#include <locale>
#include <codecvt>

Ein ausführlicheres Beispiel finden Sie hier: http://en.cppreference.com/w/cpp/locale/wstring_convert/from_bytes

1 Stimmen

Tolle Antwort, danke! ...aber folgen Sie dem Beispiel auf cppreference.com. wchar_t ist auf anderen Betriebssystemen als Windows kein 16-Bit-Typ. Sie müssen Folgendes verwenden char16_t ではなく

1 Stimmen

@CrisLuengo Danke! Ich habe die Antwort aktualisiert und verwende char16_t ではなく

4 Stimmen

Funktioniert nicht mit g++ 6.2 oder clang++ 3.8 auf lubuntu 16.04

31voto

john Punkte 78047

Hier ist etwas Code. Nur leicht getestet und es gibt wahrscheinlich ein paar Verbesserungen. Rufen Sie diese Funktion auf, um eine UTF-8 Zeichenkette in eine UTF-16 Zeichenkette zu konvertieren. Wenn sie denkt, dass der Eingabestring nicht UTF-8 ist, wird sie eine Exception auslösen, andernfalls gibt sie den entsprechenden UTF-16 wstring zurück.

std::wstring utf8_to_utf16(const std::string& utf8)
{
    std::vector<unsigned long> unicode;
    size_t i = 0;
    while (i < utf8.size())
    {
        unsigned long uni;
        size_t todo;
        bool error = false;
        unsigned char ch = utf8[i++];
        if (ch <= 0x7F)
        {
            uni = ch;
            todo = 0;
        }
        else if (ch <= 0xBF)
        {
            throw std::logic_error("not a UTF-8 string");
        }
        else if (ch <= 0xDF)
        {
            uni = ch&0x1F;
            todo = 1;
        }
        else if (ch <= 0xEF)
        {
            uni = ch&0x0F;
            todo = 2;
        }
        else if (ch <= 0xF7)
        {
            uni = ch&0x07;
            todo = 3;
        }
        else
        {
            throw std::logic_error("not a UTF-8 string");
        }
        for (size_t j = 0; j < todo; ++j)
        {
            if (i == utf8.size())
                throw std::logic_error("not a UTF-8 string");
            unsigned char ch = utf8[i++];
            if (ch < 0x80 || ch > 0xBF)
                throw std::logic_error("not a UTF-8 string");
            uni <<= 6;
            uni += ch & 0x3F;
        }
        if (uni >= 0xD800 && uni <= 0xDFFF)
            throw std::logic_error("not a UTF-8 string");
        if (uni > 0x10FFFF)
            throw std::logic_error("not a UTF-8 string");
        unicode.push_back(uni);
    }
    std::wstring utf16;
    for (size_t i = 0; i < unicode.size(); ++i)
    {
        unsigned long uni = unicode[i];
        if (uni <= 0xFFFF)
        {
            utf16 += (wchar_t)uni;
        }
        else
        {
            uni -= 0x10000;
            utf16 += (wchar_t)((uni >> 10) + 0xD800);
            utf16 += (wchar_t)((uni & 0x3FF) + 0xDC00);
        }
    }
    return utf16;
}

2 Stimmen

Danke! Danke! Es hat funktioniert... ich kann es nicht glauben :) danke für deine Zeit John

0 Stimmen

Ich bin wirklich froh, dass es geholfen hat. Es kommt wirklich nur darauf an, die richtige Frage zu stellen. Es gibt eine Menge Wissen in diesem Forum, aber Neulinge können oft nicht auf dieses Wissen zugreifen, weil sie nicht wissen, was sie fragen sollen.

1 Stimmen

@aliakbarian: Ich habe gerade einen kleinen Fehler in meinem Code entdeckt, du solltest ihn vielleicht noch einmal kopieren. Ich habe dies geändert if (j == utf8.size()) hierzu if (i == utf8.size()) .

2voto

Soren Punkte 14074

Es gibt einige relevante Fragen und Antworten aquí y aquí die es wert ist, gelesen zu werden.

Grundsätzlich müssen Sie die Zeichenkette in ein gängiges Format konvertieren - ich bevorzuge immer die Konvertierung in UTF-8, aber das kann sich ändern.

Es gibt eine Menge Software, die für die Konvertierung geschrieben wurde - die Konvertierung ist einfach und kann in ein paar Stunden geschrieben werden - aber warum nicht etwas bereits Geschaffenes aufgreifen, wie z. B. das UTF-8 CPP

0 Stimmen

Wenn Sie nur Windows verwenden: msdn.microsoft.com/de-us/library/dd319072(v=VS.85).aspx . Andernfalls verwenden Sie eine portable Bibliothek.

2voto

Yochai Timmer Punkte 46099

Um zwischen den 2 Typen zu konvertieren, sollten Sie verwenden: std::codecvt_utf8_utf16< wchar_t>
Beachten Sie die String-Präfixe, die ich zur Definition von UTF16 verwende ( L ) und UTF8 ( u8 ).

#include <string>

#include <codecvt>

int main()
{

    std::string original8 = u8"";

    std::wstring original16 = L"";

    //C++11 format converter
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert;

    //convert to UTF8 and std::string
    std::string utf8NativeString = convert.to_bytes(original16);

    std::wstring utf16NativeString = convert.from_bytes(original8);

    assert(utf8NativeString == original8);
    assert(utf16NativeString == original16);

    return 0;
}

0voto

Srijan Chaudhary Punkte 559

Microsoft hat im Rahmen seines Casablanca-Projekts, das auch als CPPRESTSDK . Dies ist unter den Namensräumen markiert Dienstprogramm::Konvertierungen .

Eine einfache Anwendung würde bei Verwendung des Namespace etwa so aussehen

Dienstprogramm::Konvertierungen

utf8_to_utf16("sample_string");

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X