Sollte man heute mehr wstring anstellen von string einsetzen?



  • Sollte man heute mehr wstring anstellen von string einsetzen? Ich meine so gut wie alles wird ja auf Unicode usw umgestellt, auch wenn wstring nicht direkt Unicode ist, macht es für euch Sinn bei neuen Programmen gleich immer auf wstring zu setzen, anstelle von std::string?



  • Die Website utf8everywhere führt eine ganze Reihe überzeugender Argumente für UTF-8 auf und ich teile diese auch weitgehend. UTF-8 wäre std::string mit entsprechender Kodierung.

    Es gibt allerdings auch das Argument, dass wenn man vornehmlich für Windows entwickelt, UTF-16 in std::wstring auch Sinn machen kann. Die Funktionen der Windows-API, welche Unicode unterstützen, arbeiten alle mit UTF-16.

    Ich persönlich verwende in meinen Programmen ausschliesslich UTF-8, nicht zuletzt aufgrund der auf utf8everywhere aufgeführten Argumente. Besonders wichtig sind mir da Speicherbedarf, ASCII-Kompatibilität und Kompatibilität mit string-verarbeitenden Funktionen in den meisten C- und C++-Bibliotheken, wo UTF-16-kodierte wchar_t* eher eine Ausnahmeerscheinung sind.

    Bei Interaktion mit der Windows-API konvertiere ich die Strings an der Schnittstelle vorher nach UTF-16 bzw. die Rückgabe-Strings wieder zurück nach UTF-8.

    Ich muss allerdings auch sagen, dass ich meist möglichst portable Software schreibe, die auf verschiedensten Systemen eingesetzt werden soll. Da ist UTF-8 meines erachtens die vernünftigste Wahl. Für ein Programm, dass ausschliesslich auf Windows laufen soll und die Windows-API massiv nutzt, kann allerdings UTF-16 durchaus nicht verkehrt sein. Man muss dann aber bedenken, dass das eine Portierung auf andere Systeme zusätzlich erschweren kann. Für meine Programme wären dann auf jeden Fall deutlich mehr Konvertierungen nach UTF-8 notwendig, als dass ich derzeit Konvertierungen nach UTF-16 für die Windows-API-Calls benötige.

    Nochwas: Für was auch immer du dich entscheidest - verwende das konsequent für alle deine Datenstrukturen und konvertiere immer nur an den Schnittstellen zu APIs, welche die jeweils andere Kodierung benötigen. Es gibt kaum etwas schlimmeres, als wenn sich inkonsistente String-Datentypen (und womöglich auch noch Kodierungen) durch das ganze Programm ziehen.



  • @CppConst sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    Ich meine so gut wie alles wird ja auf Unicode usw umgestellt, auch wenn wstring nicht direkt Unicode ist,

    Generell das, was @Finnegan gesagt hat.

    Was ich zusätzlich sagen wollte ist, dass Aussagen wie "wstring ist Unicode" (egal ob du da ein "nicht direkt" eingefügt hast) erstmal schwachsinnig nicht sinnvoll sind, weil das eine nichts mit dem anderen zu tun hat. Was wichtig ist, ist die Kodierung, in der dein Unicode-String vorliegt. Das kann utf-8 sein, utf-16 oder eben auch was anderes (wie utf-32). Gut, relevant sind wohl nur utf-8 und -16. Dementsprechend kannst du dann string oder wstring wählen. Aber Achtung: sowohl string als auch wstring wissen NICHTS über Unicode. String nimmt halt die 8-Bit-breiten und wstring die 16-Bit-breiten Wörter auf. Aber die Funktionen wie "length" oder "size" sagen dir (in beiden Versionen, mit w oder ohne) nur, wie viele "x-Bit-Wörter" im String sind, nicht wie viele Unicode-Zeichen das sind. Das ist extrem wichtig zu verstehen.

    Ich nutze nie wstring (bin aber beim Entwickeln auch nie für/unter Windows unterwegs), weil bei mir immer alle String utf-8 sind.



  • Eine weiter Information bezüglich der aussage dass "wchar_t = unicode" nicht sinnvoll ist.
    Die Größe eines wchar_t (basistyp eines std:.wstring) ist nicht genormt.
    Unter Windows ist das ein 16Bit Datentyp, mit dem man UTF-16 abbilden kann.
    Unter anderen System wie z.b. linux und macosx, ist wchar_t ein 32Bit Datentyp, mit dem man UTF-32 abbilden kann.



  • Vielen Dank für die superschnellen und kompetenten Antworten. Ich denke, ich werde dann auch den Weg über std::string mit UTF-8 Kodierung gehen.



  • @firefly sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    Ich denke, ich werde dann auch den Weg über std::string mit UTF-8 Kodierung gehen.

    • Spielt "Performance" eine Untergeordnete Rolle, ist das sicher kein schlechter Weg ....
    • soll Deine App/Bib Multiplatform sein, isses auch nicht so schlecht.

    Aber, wenn Du Deine Plattform kennst, und Performance nicht irrelevant ist, solltest hin und herkonvertieren vermeiden.
    Unter Windows Only isses gar nicht so unüblich, wide chars direkt zu benutzen.
    Noch besser, ne Bib die Dir das Abstrahiert, und mit der Plattform switcht (QString, wxString ... & co)



  • @RHBaum sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    Spielt "Performance" eine Untergeordnete Rolle, ist das sicher kein schlechter Weg ....

    Wer sagt denn, dass UTF-8 langsamer ist als UTF-16? Das Gegenteil ist oft der Fall.

    Aber, wenn Du Deine Plattform kennst, und Performance nicht irrelevant ist, solltest hin und herkonvertieren vermeiden.

    Korrekt. Das ist aber wieder eine andere Aussage als dein obiges Statement. Aber selbst hier gilt: vielleicht hast du eine komplexe String-Verarbeitung, die mit UTF-8 effizienter ist. Dann ist es möglich, dass 2x konvertieren + Verarbeitung in der besseren Kodierung schneller ist. In jedem Fall muss man dann messen.

    Unter Windows Only isses gar nicht so unüblich, wide chars direkt zu benutzen.

    Das ist auch korrekt. Aber auch hier ist die Frage immer, ob das wirklich sinnvoll ist oder ob nicht der Schritt mit konvertieren von/nach UTF-8 beim Übergeben/Returnen von WindowsApiW-Funkionen das Programm insgesamt einfacher macht. Was man auf jeden Fall machen sollte: die W-Funktionen benutzen, die A-Funktionen vermeiden.

    Noch besser, ne Bib die Dir das Abstrahiert, und mit der Plattform switcht (QString, wxString ... & co)

    "mit der Plattform switcht" - finde ich nicht gut. Dann weißt du nie, was wirklich gerade im String passiert. ABER: Seit wann switcht denn QString mit der Plattform?! Die Doku sagt das Gegenteil: "QString stores a string of 16-bit QChars, where each QChar corresponds to one UTF-16 code unit. (Unicode characters with code values above 65535 are stored using surrogate pairs, i.e., two consecutive QChars.)". https://doc.qt.io/qt-5/qstring.html



  • @wob sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    Wer sagt denn, dass UTF-8 langsamer ist als UTF-16? Das Gegenteil ist oft der Fall.

    Das sag ich nicht, es geht um das mögliche hin und her kopieren ....
    Wenn es performance technisch nicht relevant ist, brauch er sich keinen Kopf machen ...
    Wenn doch, sollte man eben checken, wie das system eingaben händelt ... und ob bibliothen (io bibs) nicht intern anfangen zu konvertieren. Wobei da meistens performance technisch nur files und netzwerk relevant sind, und da ist abgesehen von der cruden BString Serialisierung kaum was in 16bit.

    ABER: Seit wann switcht denn QString mit der Plattform?!

    Ups stimmt, der switcht wirklich nie auf 8 bit runter ...
    aber, gibts eigentlich noch(schon) ein (grafisches) OS, welches Eingaben in 8bit als "native" händelt ?



  • @RHBaum sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    Ups stimmt, der switcht wirklich nie auf 8 bit runter ...
    aber, gibts eigentlich noch(schon) ein (grafisches) OS, welches Eingaben in 8bit als "native" händelt ?

    Unter UNIX bzw. Linux sind 8Bit chars noch immer Standard, und UTF-8 wird nur dann genutzt, wenn man ein entsprechendes Locale einstellt. Der Witz an UTF-8 ist doch gerade, dass man Unicode Strings problemlos mit System Calls verwenden kann, die nur mit 8Bit Chars entworfen worden sind.

    wchar_t ist dafür 32Bit groß, d.h. es ist garantiert, dass expandierte Unicode Strings auch immer nur ein Zeichen groß sind. UTF-16 kann das nicht garantieren.



  • @john-0 sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    wchar_t ist dafür 32Bit groß, d.h. es ist garantiert, dass expandierte Unicode Strings auch immer nur ein Zeichen groß sind. UTF-16 kann das nicht garantieren.

    Ich würde behaupten, dass auch 32 Bit breite Code Units das nicht garantieren können. Unter anderem wegen:

    a (U+0061 Kleiner lateinischer Buchstabe A) + ̈ (U+0308 Verbindungszeichen Diärese) = ä (U+00E4 Kleiner lateinischer Buchstabe A mit Diärese)

    Auch ist "Zeichen" hier nicht der richtige Audruck, den du hier verwendest. Tatsächlich handelt es sich um Code Points, die nur sehr bedingt mit unserem Verständnis von "Zeichen" übereinstimmen. Das sollte für normale Programme, die lediglich mit Strings hantieren und nicht irgendwelche Unicode-Funktionen selbst implementieren, nicht wirklich relevant sein. Vor allem, da man immer noch mehrere CharT je "Zeichen" haben kann. Solche Annahmen führen irgendwann zu solch lustigen Bugs wie dass man machmal zweimal Backspace drücken muss, wenn man ein ä löschen will 😉



  • Mal von mir als Unbeteiligtem ein Kommentar:

    Würde es nicht eigentlich ausreichen, wenn man intern immer nur mit "ByteBlocks" also STL-Strings/std::vector<char> arbeitet und erst zum Zwecke der Visualisierung den Byte-Block in einen Datentypen kopiert, der das ganze lesbar macht, in welcher Form auch immer?

    Sockets unterstützen ja ohnehin nur Bytes im einfachsten Sinne, d.h. durchs ganze System treiben kann man das sowieso nicht. Und für spätere Änderungen z.B. von UTF-8 auf UTF-16 ist man doch besser bedient wenn man das nur an wenigen Stellen einsetzt. Oder sehe ich da was falsch?



  • @It0101 sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    Mal von mir als Unbeteiligtem ein Kommentar:

    Würde es nicht eigentlich ausreichen, wenn man intern immer nur mit "ByteBlocks" also STL-Strings/std::vector<char> arbeitet und erst zum Zwecke der Visualisierung den Byte-Block in einen Datentypen kopiert, der das ganze lesbar macht, in welcher Form auch immer?

    Es ist ja nicht nur Visualisierung. Wenn du Strings verarbeitest, musst du ja häufig verstehen, was drin steht. Also: was ist ein Buchstabe, was ist ein Wort etc. Denk mal allein schon die Aufgabe, alle Großbuchstaben durch Kleinbuchstaben zu ersetzen. Oder den Text in einem Ausgabefeld korrekt umzubrechen - dazu musst du nämlich die Breite der Zeichen kennen. Und wenn du da in Unicode jetzt irgendwelche Kombinationszeichen drin hast, die das vorangehende Zeichen modifizieren, dann musst du sowas alles wissen.

    Was du beschreibst (mit Ausnahme der Visualisierung), ist "dummes Durchreichen" der Daren und nicht keine wirkliche Verarbeitung. Dann braucht man in der Tat überhaupt nichts über die Kodierung zu wissen.



  • @It0101 sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    Oder sehe ich da was falsch?

    Ich sehe es zumindest genau so .....
    Wenn es um Performance geht, zählt meistens die Codierung der Eingabe und Ausgabe ... also meistens File oder Stream wo es drauf ankommt. utf-16, wcbs .... basierte Formate soll es zwar geben, die meisten sind aber ascii basiert.
    Wenn Eingabe und Ausgabe unterschiedlich sind, musst halt codieren .... am besten da wo der wenigere Durchsatz ist.

    Oft macht man sich halt aber auch erst gar keinen Kopf, weil es ganz andere Probleme zu Lösen gibt ...

    @wob
    Klar, wenn Du die Daten verarbeiten willst, musst Du sie verstehen ...
    Aber zu einem Großteil sind die Daten da in einem maschinenlesbaren Format optimiert. Und glaub das ist was lt0101 sagen wollte ... verarbeiten so lange es geht im nativen Format(ascii) .... und nur was zur Visualsierung benötigt wird konvertieren ...



  • @wob sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    @It0101 sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    Mal von mir als Unbeteiligtem ein Kommentar:

    Würde es nicht eigentlich ausreichen, wenn man intern immer nur mit "ByteBlocks" also STL-Strings/std::vector<char> arbeitet und erst zum Zwecke der Visualisierung den Byte-Block in einen Datentypen kopiert, der das ganze lesbar macht, in welcher Form auch immer?

    Es ist ja nicht nur Visualisierung. Wenn du Strings verarbeitest, musst du ja häufig verstehen, was drin steht.

    Meine Sichtweise liegt vielleicht daran, dass ich hauptsächlich im Zahlengeschäft und weniger im Text-Geschäft bin und daher mit sowas nix zu tun habe. Wenn es Daten gibt, die "verstanden" werden müssen, dann sorge ich zeitnah dafür dass die Zahlen nicht als Volltext durch die Pampa geschoben werden, sondern direkt an der Quelle schon "interpretiert" und in absolute Werte verwandelt werden. Volltext ist meistens bloat. Daher extrahiere ich die wesentlichen Dinge und "ent-bloate" somit die Datenmenge. Hübsch muss es nur am Ende sein, wenn es visualisiert wird. Und da behandle ich die Art der Codierung nicht anders als TextColor oder bold/italic 🙂 Die TextColor legst du ja auch nicht direkt nach dem Empfang aus dem Socket fest, sondern erst kurz bevor du die Daten visualisierst.

    Aber ja ich gebe dir recht. Wenn man im reinen Text-Geschäft ist, muss man sicherlich die Codierung zeitnah anfassen.



  • @Finnegan sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    Ich würde behaupten, dass auch 32 Bit breite Code Units das nicht garantieren können. Unter anderem wegen:

    a (U+0061 Kleiner lateinischer Buchstabe A) + ̈ (U+0308 Verbindungszeichen Diärese) = ä (U+00E4 Kleiner lateinischer Buchstabe A mit Diärese)

    Das sind aber Probleme der Schrift und nicht der Zeichen. Der Grundgedanke von Unicode war, dass man solche zusammengesetzte Zeichen wie auf der Schreibmaschine nicht mehr braucht. Jedenfalls ist mit einem wstring auf einem UNIX/Linux garantiert, dass es immer ein Zeichencode für ein Unicode Code Point ist, und sich Code Points nicht auf mehrere Stellen verteilen.



  • @john-0 sagte in Sollte man heute mehr wstring anstellen von string einsetzen?:

    Der Grundgedanke von Unicode war, dass man solche zusammengesetzte Zeichen wie auf der Schreibmaschine nicht mehr braucht.

    Naja, aber ob dieser Gedanke noch gültig ist...

    Du kannst ein ä zum Beispiel als einzelnes Zeichen haben oder aus einem a und den Pünktchen zusammensetzen - wie @Finnegan geschrieben hat. Aber denk vor allem auch mal in die Emojis. Du kannt einen Daumen hoch haben - und den in mehreren Farben, im Simpsons-Gelb oder aber in diversen verschiedenen Hauttönen. Das sind nicht separate Zeichen, sondern ein Daumen-Emoji modifiziert mit einem Farbzeichen. Und das geht dann nicht mehr als einzelnes Zeichen.



  • M̯̼̜̃͂͋̃͊͊a̧̾̆͡͝n͚̹͋͗̾ͅ k͚̰͚͋̃ă̢̡͚͋͜͜n̛̼̮̥̮͂̑n͚̥͂͑͂͡ ȩ̧̛̜͌͂͝͡ş̑͗̐͌̆͜ m̜̥̯̜̥͒͒ͅį̡̥͌͌̃̾͠ͅt̡̢̛̛͗̾͝ d̢̯̼̹̉̊͒͠ȩ̨̫̼͋̉͑͠n̢͗̐̐͋͡ Ṽ̢̫̼̰̜͗̉̾ĕ̼̼͗̉̾ŗ̥̼͂͂̐͝b̡̫̮̥͂͝ĭ͚̮̉̉̉n̢̡̹̆̉d̼̜͒͋͌̊͜͡ͅư̡̡̫͚͒͠͝ͅn̢̧̹͂̆g̛̥̾͒̑͑͜͜s̨̡̢̡͚͒͌̃ͅz̮̫̆̾͒̐͜e̾̊̾͗͂ĩ̢̼̑͗͗c̨̧͚̫̑̐͜͡ḫ̥͊̉͌̆͠e̡̢̛̯͊̆͊̾n̰̥̼͚̯̾̆ a̡̢͚͊͠͠ų̧̮̜͑͑͗͡c̛̛̫̜͗͋͑ͅh̡̥̼͚̼̃͊͜ z̰̰̼͗̊͝i̛̛͚̰̫͋̆͜ͅe̡̥͊̃͡͠m̛̰̰̯̉̉̐͝͠ļ̡̮̜͌i̼̰͗͜͡ͅc̡̛̰̥̃͋̃͒̐h̨̛̰͂̃̊͡͡ͅ w̢̹͗̑͊͑̆į͚̹̥͗͒̐̃ͅl͑̃͌͠ͅͅd̥̯͚̹̉͜ t̡̛̼̼̐͝͡͡r̛̹̯̰͌̑͜ẻ̢͚̫̹̹̰̫ͅĩ̧̉͋͋͜b̰̥͚̰͌̾͂͋ͅe̜̼̜̜͑̾n̡̫̜͗͌͑.̮̰̑͂̐͝

    Man kann es mit den Verbindungszeichen auch ziemlich wild treiben.

    Da reichen die wenigen Code Points in Unicode bei weitem nicht, um allen möglichen "Zeichen"* einen individuellen Code zuzuordnen. Just sayin' 😉

    * oder besser "Graphem-Cluster", das was wir hier wohl am ehesten meinen, wenn wir von "Zeichen" sprechen.


Log in to reply