wstring vs string - kurze Nachfrage



  • Hi,

    wie war das noch gleich? Ich meinte vor kurzem gehört zu haben, dass string eigentlich ausreicht. Aber QString::toStdString() konvertiert mir die Eurozeichen zu '?'... wenn ich es zu wstring konvertiere, klappt's. Also hat wstring doch seine Existenzberechtigung?

    Gruß,
    Eisflamme



  • Eisflamme schrieb:

    Also hat wstring doch seine Existenzberechtigung?

    Theoretisch gesehen ist wstring absolut sinnlos, nur auf falsch konfigurierten Konsolenfenstern(?) kann das unter Plattformen, die einen strategischen Fehler gemacht haben und defaultmässig auf UTF-16 setzen (Windows?) nötig scheinen.
    Vielleicht bekommst du mit wstring was hin, was auf deinem Rechner läuft.
    Aber auf einer anderen Plattform geht es ziemlich sicher nicht mehr. Ist halt so, wenn man sich nicht mit Encodings beschäftigt.
    Wenn du dich hingegen mit Encodings beschäftigst, hast du im Normalfall keinen Bedarf für wstring.



  • Bei mir geht's nicht um die Ausgabe, ich will nur parsen. Also sagst Du, dass QString::toStdString() falsch arbeitet oder wie? Aber ein einfacher char kann doch nach wie vor nur 255 Zeichen halten, das ist doch per se schon limitiert.



  • Eisflamme schrieb:

    Bei mir geht's nicht um die Ausgabe, ich will nur parsen. Also sagst Du, dass QString::toStdString() falsch arbeitet oder wie? Aber ein einfacher char kann doch nach wie vor nur 255 Zeichen halten, das ist doch per se schon limitiert.

    Woher meinst du zu wissen, dass das Eurozeichen zu '?' wird?

    Zum Parsen ist wstring übrigens absolut ungeeignet, da ist string genauso gut. Oder sagen wir so, man meint schnell, wstring sei besser, aber sobald mit chinesischen Zeichen ins Spil kommen, hat wstring das gleiche Problem.

    Informier dich mal über UTF-8, dann siehst du, dass auch mehrere chars zusammengehören können. Du darfst dann halt nicht operator[] verwenden und auf Zeichen einzeln zugreifen, aber das darfst du bei wstring auch nicht.

    Leider fehlt C++ der Unicode-Support, daher wirst du eine Bibliothek dafür benötigen.



  • Vielleicht solltest du die Qt Dokumentation lesen?



  • Woher meinst du zu wissen, dass das Eurozeichen zu '?' wird?

    Ist nicht schwierig rauszufinden. Ich habe es getestet, daher frage ich doch hier nach. Das resultierende Zeichen hat auch den gleichen Zahlencode wie '?', falls Du mir unterstellen willst, ich hätte nur das '?' in einer Ausgabe gesehen.

    Ich brauche keine chinesischen Zeichen. Aber das Eurozeichen ist eben drin.

    manni66:
    Sehr spezifisch. Das Einzige, was ich dort fand, was Du meinen könntest:

    If the QString contains Unicode characters that the QTextCodec::codecForCStrings() codec cannot handle, using this operator can lead to loss of information.

    wusste ich schon vorher. Gibt es eine Alternative?



  • Eisflamme schrieb:

    manni66:
    Sehr spezifisch. Das Einzige, was ich dort fand, was Du meinen könntest:

    If the QString contains Unicode characters that the QTextCodec::codecForCStrings() codec cannot handle, using this operator can lead to loss of information.

    wusste ich schon vorher. Gibt es eine Alternative?

    QByteArray QString::toLatin1 () const schrieb:

    The returned byte array is undefined if the string contains non-Latin1 characters. Those characters may be suppressed or replaced with a question mark.

    Wenn du keinen QTextCodec setzt, wird toLatin1 benutzt => setze den passenden QTextCodec.

    Lesen der Qt Dokumentation bedeutet auch, den "siehe auch" Links zu folgen!



  • existenzialismus schrieb:

    Zum Parsen ist wstring übrigens absolut ungeeignet, da ist string genauso gut. Oder sagen wir so, man meint schnell, wstring sei besser, aber sobald mit chinesischen Zeichen ins Spil kommen, hat wstring das gleiche Problem.

    std::wstring ist lt. Standard std::basic_string< wchar_t > . Weiter ist wchar_t der Typ, der alle(!) Zeichen des größten verwendeten Zeichensatzes aufnehmen soll/kann.

    C++-Standard schrieb:

    Type wchar_t is a distinct type whose values can represent distinct codes for all members of the largest
    extended character set specified among the supported locales (22.3.1).

    Die Unicodes von CJK Extension-A liegen im Bereich von 0x3400 bis 0x4DB5, dass sind immerhin über 6500 Zeichen und damit wahrscheinlich mehr als die meisten Chinesen beherrschen. Also hier reichen 16Bit noch hin und weitere Zeichen mit höheren Codes können auf einem System dann eben nicht mehr mit Standardmitteln verarbeitet werden.
    Was noch lange nicht bedeutet, dass das dann mit UTF-16 oder einem anderen Encoding funktioniert. Ein basic_string<>, der als Text und nicht als ein Abbild eines Festplatteninhalts interpretiert wird, sollte IMHO überhaupt kein Encoding enthalten.

    Die Kodierungen von Big5 und GB2312 kommen auch mit 16Bit aus.

    existenzialismus schrieb:

    Leider fehlt C++ der Unicode-Support, daher wirst du eine Bibliothek dafür benötigen.

    wozu auch? C++ ist nicht auf eine Codierung festgelegt. Und wie sähe denn eine 'Bibliothek mit Unicode-Support' aus?

    Gruß
    Werner



  • Lesen der Qt Dokumentation bedeutet auch, den "siehe auch" Links zu folgen!

    Genau, ich lese die gesamte QT Dokumentation durch und folge allen "siehe auch"-Links. Sorry, aber wenn Du weißt, was ich Deiner Meinung nach nachschlagen soll, dann sag es doch einfach statt einen minder sinnvollen Hinweis wie "Les die QT Dokumentation" zu geben... nett gemeint, danke, aber war für mich nicht hilfreich.

    Dein Zitat erzählt mir wieder nichts Neues, auch das wusste ich schon vor Starten des Threads.

    Wenn du keinen QTextCodec setzt, wird toLatin1 benutzt => setze den passenden QTextCodec.

    Der Hinweis ist hilfreich, dankeschön. 🙂

    Werner: Wie würdest Du mein Problem dann wohl lösen?



  • Also hat wstring doch seine Existenzberechtigung?

    Ähh, diese Frage finde ich schon verwirrend.

    Du solltest dich mal mit Unicode, Codepages und Kodierungen auseinandersetzen.



  • Eisflamme schrieb:

    Also hat wstring doch seine Existenzberechtigung?

    Hier ist der Umgang mit Breitzeichen toll erklärt.



  • [upper] schrieb:

    Eisflamme schrieb:

    Also hat wstring doch seine Existenzberechtigung?

    Hier ist der Umgang mit Breitzeichen toll erklärt.

    Jürgen Wolf?

    Bitte ein Bit:
    Ist richtig. Wo fange ich da am besten an? Gibt es da eine gute Seite, die auch die C++-Implementierung diskutiert?

    Meine Frage, ob "wstring" seine Existenzberechtigung hat, rührt nämlich daher, dass ich zwar theoretisch weiß, was dahintersteckt, aber im Gedächtnis habe, dass hier vielfach gesagt wurde, dass string eigentlich genau so funktionieren kann (ich weiß nicht mehr wie, vll einfach durch zwei char pro Zeichen im string) und wstring daher unnötig ist.





  • Eisflamme schrieb:

    Bei mir geht's nicht um die Ausgabe, ich will nur parsen. Also sagst Du, dass QString::toStdString() falsch arbeitet oder wie? Aber ein einfacher char kann doch nach wie vor nur 255 Zeichen halten, das ist doch per se schon limitiert.

    vllt wäre es nicht schlecht wenn du verräts, was du eigentlich parsen willst bzw. in welcher kodierung?



  • Eisflamme schrieb:

    Meine Frage, ob "wstring" seine Existenzberechtigung hat, rührt nämlich daher, dass ich zwar theoretisch weiß, was dahintersteckt, aber im Gedächtnis habe, dass hier vielfach gesagt wurde, dass string eigentlich genau so funktionieren kann (ich weiß nicht mehr wie, vll einfach durch zwei char pro Zeichen im string) und wstring daher unnötig ist.

    Jein. Du kannst in einem std::string UTF8-kodierte Codepoints speichern und damit den gesamten Unicode-Raum abdecken. UTF8 hat viele nette Eigenschaften, die das ganze relativ straightforward machen, dennoch gibt es einige Dinge zu beachten.

    Ein Unicode-Codepoint in UTF-8-Kodierung kann dann mehrere Bytes (bis zu 4, theoretisch ginge auch noch mehr) in Anspruch nehmen. Gleichzeitg behalten die Codepoints unterhalb von 128 ihren von ASCII gewohnten Wert.

    Sachen, bei denen du dann natürlich aufpassen musst, ist z.B. das Splitten von UTF8-Strings. Du kannst nicht einfach an jedem beliebigen Index splitten. An einem bestimmten Codepoint splitten, ist aber immer noch trivial.

    IMHO ist UTF-8 immer noch die mit Abstand netteste Art und Weise mit kodiertem Unicode umzugehen. Die Links von theta sind schon mal ein guter Anfang. Weiter gehts hier (weiterführende Links beachten):
    http://research.swtch.com/utf8



  • Eisflamme schrieb:

    Werner: Wie würdest Du mein Problem dann wohl lösen?

    Hallo Eisflamme,

    Wenn Du dieses Problem meinst:

    Eisflamme schrieb:

    QString::toStdString() konvertiert mir die Eurozeichen zu '?'... wenn ich es zu wstring konvertiere, klappt's. Also hat wstring doch seine Existenzberechtigung?

    und Du den String nachher nur parsen möchtest, so würde ich QString::toStdWString() vorschlagen und anschließend parst Du den std::wstring . Die Zeichen sind dann halt vom Typ wchar_t und nicht char - ansonsten wie gehabt.
    Lt. Doku wird bei toStdString nach UTF-16 konvertiert, also musst Du theoretisch noch sicherstellen, dass bei keinem der Zeichen das Bit15 gesetzt ist. In der Praxis (nur europäische gängige Zeichen - z.B. '€') kannst Du Dir das wahrscheinlich sparen (s. mein Hinweis auf die Codes der chinesischen Zeichen oben). D.h. Du hast einen Text vor Dir, der eins zu eins in jedem Element genau ein Zeichen enthält.

    Wenn Du nur sehr wenige Zeichen hast, die >0x7f sind, könntest Du Dir auch eine eigenen CodePage definieren und diese Zeichen im Bereich von 0xA1 bis 0xFF unterbringen. Das müsste über QTextCodec::setCodecForLocale funktionieren. Anschließend kannst Du dann mit QString::toLocal8Bit ein QByteArray erzeugen, welches man dann in einen std::string konvertieren muss.

    Gruß
    Werner

    Nachtrag: ich sehe gerade, dass in CP858 das Euro-Zeichen (Code 0xD5) enthalten ist.



  • Hi,

    danke allerseits! Habe den ersten Artikel von theta komplett gelesen. wchar_t ist also UCS-2 = UTF-16. Da das eine Unicode-Art ist, kann man also durchaus sagen, dass C++ einen Teil des Unicodes unterstützt. Bietet irgendeine Bibliothek (boost oder so) denn eine UTF-8-Stringklasse an, auf die man mit [] korrekt zugreifen kann?

    pars0r:
    Eigentlich ist das fast alles nur im Bereich von Bit 0-127. Einzig dazu kommen die Währungszeichen Pfund und Euro.

    Insofern wäre eine eigene Codepage vielleicht gar nicht schlecht. Aber wstring erscheint mir gerade einfacher. Was spricht denn dagegen?



  • Ist richtig. Wo fange ich da am besten an? Gibt es da eine gute Seite, die auch die C++-Implementierung diskutiert?

    http://en.wikipedia.org/wiki/Code_page
    http://en.wikipedia.org/wiki/Utf8
    http://en.wikipedia.org/wiki/UTF-16
    http://en.wikipedia.org/wiki/Unicode
    http://msdn.microsoft.com/en-us/library/windows/desktop/dd317711%28v=vs.85%29.aspx
    http://msdn.microsoft.com/en-us/library/windows/desktop/dd317752%28v=vs.85%29.aspx

    Meine Frage, ob "wstring" seine Existenzberechtigung hat, rührt nämlich daher, dass ich zwar theoretisch weiß, was dahintersteckt, aber im Gedächtnis habe, dass hier vielfach gesagt wurde, dass string eigentlich genau so funktionieren kann (ich weiß nicht mehr wie, vll einfach durch zwei char pro Zeichen im string) und wstring daher unnötig ist.

    Wenn man es streng nimmt, ist dies Blödsinn. Schreibe mal in deinem String: "Schräglage: β = 1.5"

    Natürlich kann man std::string als einen String in einer speziellen Kodierung auffassen. Aber damit unterläuft man die eigentliche Bedeutung von std:string bzw. std::basic_string<char>.



  • Werner Salomon schrieb:

    Lt. Doku wird bei toStdString nach UTF-16 konvertiert

    Du meinst hier sicher toStdWString. Das gilt dann auch nur wenn wchar_t 2 Byte hat. Falls wchar_t 4 Byte hat wird ucs4 verwendet.




Anmelden zum Antworten