2014-09-27 8 views
5

Ich versuche, eine UTF-8-Zeichenfolge durchlaufen. Das Problem, wie ich es verstehe, ist, dass UTF-8-Zeichen variable Länge haben, so kann ich Char-by-char nicht einfach iterieren, aber ich muss eine Art von Konvertierung verwenden. Ich bin sicher, dass es im modernen C++ eine Funktion dafür gibt, aber ich weiß nicht, was es ist.Iterating durch eine UTF-8-Zeichenfolge in C++ 11

#include <iostream> 
#include <string> 

int main() 
{ 
    std::string text = u8"řabcdě"; 
    std::cout << text << std::endl; // Prints fine 
    std::cout << "First letter is: " << text.at(0) << text.at(1) << std::endl; // Again fine. So 'ř' is a 2 byte letter? 

    for(auto it = text.begin(); it < text.end(); it++) 
    { 
    // Obviously wrong. Outputs only ascii part of the text (a, b, c, d) correctly 
    std::cout << "Iterating: " << *it << std::endl; 
    } 
} 

Zusammengestellt mit clang++ -std=c++11 -stdlib=libc++ test.cpp

Von dem, was ich wchar_t und wstring sollte nicht verwendet werden, gelesen habe.

+0

Es gibt keine "UTF-8-Zeichen". Bis Sie mit dem Thema vertraut sind, wird es frustrierend und unwillig, in den Code zu schreiben. –

+0

Sind Sie auf einem Unixoid oder auf Windows? Und wollen Sie Codeunits, Codepoints oder Grapheme? (Charakter ist lächerlich kontextabhängig (und selbst der Kontext ist möglicherweise nicht genug, um zu entscheiden), und es gibt zusätzliche Schmerzen im Laden unter Windows) – Deduplicator

+1

Sie können sich hier [http://en.cppreference.com/w/cpp/locale/wstring_convert/from_bytes). Bedenken Sie, dass es in gcc nicht funktioniert, sie haben diesen Teil des Standards noch nicht implementiert, funktionieren aber in clang/libC++ und sollten mit VS2013 IIRC funktionieren. –

Antwort

3

Als n.M. Ich schlug vor, verwenden std::wstring_convert:

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

int main() 
{ 
    std::u32string input = U"řabcdě"; 

    std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter; 

    for(char32_t c : input) 
    { 
    std::cout << converter.to_bytes(c) << std::endl; 
    } 
} 

Vielleicht soll ich eindeutig in der Frage angegeben mehr habe, was ich wollte wissen, ob dies möglich war ++ 11 ohne die Verwendung von Drittanbieter-Bibliotheken wie ICU zu tun, in C oder UTF8-CPP.

+0

Welche Version von g ++ hast du benutzt? es könnte ein Teil von C++ sein 14 – Splash

+0

Ich benutze clang: Apple LLVM Version 7.0.0 (clang-700.0.72), aber das ist alles C++ 11. Sie können überprüfen, http://en.cppreference.com –

+0

Ich lief unter http://en.cppreference.com/w/cpp/locale/codecvt_utf8, und wählte die 4.9 Version C++ 11, und es tut nicht t kompilieren. Könnten Sie einen Blick darauf werfen? – Splash