[gelöst] Umlaute in QString aus stdString



  • Ich entwickel mit dem QtCreator unter Ubuntu 14.04.

    Ich bin sicher, dass es UTF-8 ist, der Linuxkonsolen-Befehl "file -bi" gibt mir als charset UTF8 an und im Hex-Editor werden die Umlaute mit 2 Bytes kodiert angezeigt.

    Dein Vorschlag funktioniert leider nicht, bleibt die gleiche Ausgabe. Ich habe die testFile.txt vor dem Durchlauf auch gelöscht, damit sie neu angelegt wird.

    Vielleicht ist es einfach ein "Ubuntu-Problem", die Group-Boxes werden auch nicht gezeichnet. (Das ist keine Frage nach Hilfe, gibt schon einen längeren Thread dazu 😉 )

    VG
    Cherup

    Edit:
    Ich hab nochmal versucht für FileData als Typ den std::wstring zu nutzen und die Rückgabe und die QLabel-Textzuweisung entsprechend auf wString umgestellt.
    Ebenfalls kein Erfolg. Es werden allerdings andere Zeichen angezeigt



  • hier wird aus einer kleinen Sache aber ein großer Schuh/Thread!

    Du ließt die Datei byteweise in einen std:string.
    std:string ist für "single-byte characters" ausgelegt!
    http://www.cplusplus.com/reference/string/string/

    Note that this class handles bytes independently of the encoding used: If used to handle sequences of multi-byte or variable-length characters (such as UTF-8), all members of this class (such as length or size), as well as its iterators, will still operate in terms of bytes (not actual encoded characters).

    std::wstring ist für 2-Byte-Zeichen ausgelegt. Wenn du also deine Datei in Unicode 16-Bit wandelst und std::wstring verwendest sollte es gehen.

    Ich kenne keine std-C-Funktion für codec-Wandlung, deshalb nutzt man unter Windows dafür auch die Windows-Funktion MultiByteToWideChar etc.
    Deshalb die Empfehlung komplett Qt zu verwenden.



  • Softwaremaker schrieb:

    hier wird aus einer kleinen Sache aber ein großer Schuh/Thread!

    Aber auch nur weil Cherup zuwenig informationen liefert.

    Softwaremaker schrieb:

    QString::fromStdString() nutzt intern QString::fromUtf8(const char * str, int size = -1)

    Stimmt aber nur für Qt5

    Laut der Dokumentation von Qt 4 verwendet QString::fromStdString intern QString::fromAscii

    http://doc.qt.io/qt-4.8/qstring.html#fromStdString

    http://doc.qt.io/qt-5/qstring.html#fromStdString

    Und da es bei Ihm mit QString::fromStdString nicht klappt vermute ich dass er Qt4 verwendet.

    Wenn ich QString::fromUtf8 verwendet passt es immer. (Egal ob Qt4 oder Qt5)

    QString::fromUtf8(FileData.data(), static_cast<int>(FileData.size()));
    


  • Morgen,

    warum liefere ich zu wenig Infos? Ich habe bereits im ersten Beitrag geschrieben, dass ich als OS Linux nutze, auf die Idee nachzuschauen, ob die Datei in UTF8 ist bin ich erst durch euch gekommen und die FileRead-Funktion habe ich auch recht früh gepostet.
    Zugegeben, die Qt-Version habe ich noch nicht geschrieben, die ist übrigens 5.2.
    Und ja ich hätte auch das Minimalbeispiel früher posten können.
    Ich werde versuchen, in Zukunft möglichst mehr Infos in den Startbeitrag zu packen.

    Ich möchte nach wie vor kein Qt in meiner Kern-Logik haben, die GUI soll als Modul bleiben. Ich werden mir mal in der Qt-Referenz QString::fromUTF8 anschauen um zu verstehen, was du mit deinem Codebeispiel meinst. Und mal sehen, was die Boost-Library für den Daten-IO hergibt.

    Cherup



  • ich würde dann als Puffer zum Einlesen der Daten aus der Datei keinen std:string verwenden. Besser den Speicher mit malloc usw. anlegen, darin die Datei einlesen und dann den Zeiger und Größe an QString mit fromUtf8 übergeben.
    Wenn die Daten von Qt wieder in die Datei sollen, dann mit QString::toUtf8 ein QByteArray erzeugen und dieses hat ::constData() und ::size() das an die Datei-Schreibfunktion übergeben wird.



  • Cherup schrieb:

    Zugegeben, die Qt-Version habe ich noch nicht geschrieben, die ist übrigens 5.2.

    Sicher das du Qt5 in deinem Programm verwendest? Qt Creator kennt verschiedene Kits, die wiederum beschreiben welche Qt Version und für welche Platform (z.b. Desktop, Android) das Programm übersetzt werden soll.

    Und mein code beispiel zeigt wie in Qt 5 QString::fromStdString intern QString::fromUtf8 aufruft. Nur auf den namen der std::string variable in einem lauffähigen Beispiel gemünzt



  • Softwaremaker schrieb:

    ich würde dann als Puffer zum Einlesen der Daten aus der Datei keinen std:string verwenden. Besser den Speicher mit malloc usw. anlegen, darin die Datei einlesen und dann den Zeiger und Größe an QString mit fromUtf8 übergeben.

    Wiso kein std::string verwenden und stattdessen manuelles speicher management betreiben?
    Wenn schon kein std::string dann eher ein std::vector<char>



  • firefly schrieb:

    Wiso kein std::string verwenden und stattdessen manuelles speicher management betreiben?
    Wenn schon kein std::string dann eher ein std::vector<char>

    Mache wenig mit std, deswegen konnte ich nur malloc nennen. Aber jedenfalls sollte er nicht std::string verwenden, das würde den Eindruck erwecken, das dort ein Ein-Byte-Encoded-Text enthalten ist, ist aber ein Utf-8, die std:string-Funktionen sind alle für Ein-Byte-Encoded-Text ausgelegt.
    Deine Empfehlung mit std::vector<char> passt.



  • Softwaremaker schrieb:

    firefly schrieb:

    Wiso kein std::string verwenden und stattdessen manuelles speicher management betreiben?
    Wenn schon kein std::string dann eher ein std::vector<char>

    Mache wenig mit std, deswegen konnte ich nur malloc nennen. Aber jedenfalls sollte er nicht std::string verwenden, das würde den Eindruck erwecken, das dort ein Ein-Byte-Encoded-Text enthalten ist, ist aber ein Utf-8, die std:string-Funktionen sind alle für Ein-Byte-Encoded-Text ausgelegt.
    Deine Empfehlung mit std::vector<char> passt.

    Okay das war jetzt genug Unfug. std::string ist DIE Wahl, wenn man mit UTF8 hantiert. Der Vollständigkeit halber: für UTF16 gibt’s std::u16string und für UTF32 gibt’s std::u32string . Fang bloß nicht an mit std::wstring herumzubasteln, das ist für nichts zu gebrauchen.
    So wie Cherup die Datei einliest ist schon in Ordnung, es muss also ein Qt Problem sein den String korrekt als UTF8 zu interpretieren. Da ich keine Ahnung von Qt habe, kann ich da nicht behilflich sein.



  • Biolunar schrieb:

    Okay das war jetzt genug Unfug. std::string ist DIE Wahl, wenn man mit UTF8 hantiert. Der Vollständigkeit halber: für UTF16 gibt’s std::u16string und für UTF32 gibt’s std::u32string . Fang bloß nicht an mit std::wstring herumzubasteln, das ist für nichts zu gebrauchen.
    So wie Cherup die Datei einliest ist schon in Ordnung, es muss also ein Qt Problem sein den String korrekt als UTF8 zu interpretieren. Da ich keine Ahnung von Qt habe, kann ich da nicht behilflich sein.

    Nur muss er dann bei utf-8 aufpassen, string::size liefert nicht die Anzahl der Zeichen sondern der Bytes, bei wstring::size und unicode-16 bekommt er die Anzahl der Zeichen, was dann die Hälfte der Byte-Anzahl ist. Es ging mir nur um den falschen Eindruck der bei der Verwendung von string für Utf-8 ensteht, da finde ich std::vector<char> eindeutiger, auch wenns letztendlich das gleiche ist.
    Mein Post mit wstring war ungünstig formuliert, sollte keine Empfehlung sein Unicode-16 bzw. wstring zu verwenden.

    @Cherup: verwende mal in Qt nicht fromStdString sondern fromUtf8.



  • Softwaremaker schrieb:

    Nur muss er dann bei utf-8 aufpassen, string::size liefert nicht die Anzahl der Zeichen sondern der Bytes

    Das stimmt.

    Softwaremaker schrieb:

    bei wstring::size und unicode-16 bekommt er die Anzahl der Zeichen, was dann die Hälfte der Byte-Anzahl ist.

    Das ist falsch. UTF16 ist kein single char encoding, sondern wie UTF8 auch ein multi char encoding. Jedes Zeichen, was überhalb der BMP liegt wird durch zwei u16char_t dargestellt.
    Im Übrigen ist nicht definiert wie groß ein wchar_t ist. Z.B ist unter Windows wchar_t üblicherweise 2 Byte groß (also groß genug für UTF16), während unter Linux es üblicherweise 4 Byte groß ist.



  • Oje,

    Was hab ich da nur losgetreten 😃

    Ein ganz großes JUHU und ein dickes Danke an euch, mit

    QString::fromUtf8(FileData.data(), static_cast<int>(FileData.size()));
    

    funktioniert es endlich 🙂

    Ich hab schon Stunden nach einer Lösung gesucht, bevor ich hier gefragt habe 🙂

    Viele Grüße
    Cherup


Anmelden zum Antworten