UTF8 mit und ohne BOM

  • C++

Es gibt 17 Antworten in diesem Thema. Der letzte Beitrag () ist von Gonger96.

    UTF8 mit und ohne BOM

    Moin Leute,
    in einem Qt-Projekt (GUI mit QString, Daten in std::string) werden UTF8-Dateien über fread eingelesen,
    der Inhalt (char*) wird mit

    C-Quellcode

    1. std::string config(fileContent);
    zu einem std::string konvertiert.
    Leider habe ich bei der weiteren Bearbeitung Probleme, wenn die Datei mit BOM anfängt:
    .
    Nun hab ich über den Umweg QString folgenden funktionierenden Zustand:

    C-Quellcode

    1. // UTF8: ggf. BOM unterdrücken
    2. QString qstring = QString::fromUtf8(fileContent);
    3. std::string config(qstring.toUtf8());
    Die Verwendung von QString ist da eher suboptimal. Kennt jemand eine std::-Methode, die dasselbe macht?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @Quadsoft:: Danke, aber solch wollte ich eigentlich vermeiden. :S
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    RodFromGermany schrieb:

    aber solch wollte ich eigentlich vermeiden.

    Hä? Ich denke du willst die BOM übergehen? Die hat immer dieselben 3 Bytes. Das ist die effektivste und effizienteste Möglichkeit, das zu tun. Oder sind dir 2MB große Bibliotheken, die dir diese eine if-Abfrage plus die Pointer-Verschiebung abnehmen, lieber?
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Übersichtlicher:

    PHP-Quellcode

    1. int32_t bom = *static_cast<int32_t*>(fileContent) >> 8;
    2. if (bom == 0x00EFBBBF) { ... }
    To make foobar2000 a real random music player, I figured out the only way to achieve this is to use Windows Media Player.

    At some point in time, you recognize that knowing more does not necessarily make you more happy.
    Wenn du unbedingt die STL dafür nutzen willst (wovon ich dir in diesem Fall abrate, dafür hast du Qute), dann kann folgender Beitrag sinnvoll sein: stackoverflow.com/questions/10…ithout-external-libraries
    Nur bitte benutz kein std::wstring sondern weiterhin std::string (oder std::vector<char>).
    To make foobar2000 a real random music player, I figured out the only way to achieve this is to use Windows Media Player.

    At some point in time, you recognize that knowing more does not necessarily make you more happy.

    Gonger96 schrieb:

    Wieso eigentlich per fread ?
    Das ist ein Steinkohle-Projekt, für das ich nur mal schnell eben ein paar einzulesende Konfigurationsfiles schreiben sollte, aber es kam halt anders.
    Da in der Beschreibung UTF8 vorschrieben ist, habe ich (momentan) auch keinen tiefergehenden Handlungsbedarf.
    @Arby:: Die Bibliotheken sind sowieso da (Qt-Projekt unter Verwendung der stl :rolleyes: ), inkonsequent bis zum Get No.
    Nu hab ich eine Nacht drüber geschlafen und hab mich für die Variante von @Chrisber: entschieden, allerdings meckert der Compiler permanent bei static_cast und const_cast rum, da hab ich mal die gute alte Union ausgegraben:

    C-Quellcode

    1. union UTF8
    2. {
    3. char* text;
    4. __int32* bom;
    5. };
    6. UTF8 utf8;
    7. utf8.text = fileContent;
    8. __int32 bom = *utf8.bom >> 8;
    9. if (bom == 0x007bbfbb)
    10. {
    11. // Remove BOM
    12. fileContent += 3;
    13. }
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany: Achtung! Habe es falsch gemacht oben... Liegt an der Endianess von Windows und Linux und daran, dass uint verwendet werden sollte (auch der Shift muss demnach umgedreht werden). Vermutlich ist die Array-Check-Methode doch besser, da du so keine Abhängigkeiten hast ;-)

    Lösung:

    PHP-Quellcode

    1. #include <iostream>
    2. using namespace std;
    3. int main() {
    4. char test[] = { 0xEF, 0xBB, 0xBF, 0x83 };
    5. char *fileContent = test;
    6. uint32_t bom = *reinterpret_cast<uint32_t*>(fileContent) << 8;
    7. std::cout << "Original: " << std::hex << *reinterpret_cast<uint32_t*>(fileContent) << std::endl;
    8. std::cout << "Shifted: " << std::hex << bom << std::endl;
    9. if (bom == 0xBFBBEF00u) // Endianess beachten!
    10. {
    11. std::cout << "BOM!" << std::endl;
    12. fileContent += 3;
    13. }
    14. else
    15. {
    16. std::cout << "NO BOM!" << std::endl;
    17. }
    18. return 0;
    19. }


    Ausgabe:

    Quellcode

    1. Original: 83bfbbef
    2. Shifted: bfbbef00
    3. BOM!
    To make foobar2000 a real random music player, I figured out the only way to achieve this is to use Windows Media Player.

    At some point in time, you recognize that knowing more does not necessarily make you more happy.

    Chrisber schrieb:

    Achtung!
    Hab ich schon gemerkt, den Code hab ich getestet und er läuft, aber ich hab dann doch noch den Byte-Einzelvergleich genommen.
    Das mit der Union hab ich gemacht, weil sich die Casts iwie nicht compilieren ließen.
    Danke.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    Gonger96 schrieb:

    Das ist nämlich ein ziemlicher Betrug am Compiler, OO ist anders.

    Ich möchte nicht wissen, mit wieviel "Betrug am Compiler" damals so überraschende Entwicklungen wie die ihrer Zeit weit voraus eilende 3D-Engine aus "Doom" von id-Software hingezaubert wurden... :D
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Das habe ich auch nicht behauptet. Der Code oben hat aber auch absolut nichts mit OO zu tun.
    To make foobar2000 a real random music player, I figured out the only way to achieve this is to use Windows Media Player.

    At some point in time, you recognize that knowing more does not necessarily make you more happy.