wstring wifstream und getline



  • Moin, einfaches Problem - eigentlich, ich finde dazu vieles im Netz aber nichts was so richtig will.

    Ich habe mittels ifstream eine xml-Datei ausgelesen, alles lief wunderbar. Dann fiel mir auf, dass da div. Zeichen drinstehen, die der normale string nicht kann, also habe ich alles auf wstring umgestellt und aus dem ifstream ein wifstream gemacht.

    Jetzt mache ich da ein getline() und er gibt mir immer(!) einen leeren wstring zurück. Der Compiler hat alles anstandslos gefressen (was nicht viel heißen muss).

    Hier der Code:

    wstring wstrBuffer;
    wstring wstrFileName=L"ich bin eigentlich ein Pfad mit Dateiname";
    
    wifstream myFile;
    
    //halte diese Zeile schon für fragwürdig, Lösung aus dem internet...
    myFile.open((char*)wstrFileName.c_str()); 
    
    if(myFile.is_open())
    {
       //hier kommt er auch brav immer herein, d.h. das open scheint geklappt zu haben
       myFile.seekg(ios::beg);
       while(!myFile.eof())
       {
          getline(myFile,wstrBuffer);
          if(wstrBuffer.empty())
             continue; // hier kommt er immer und unendlich oft an, in der Datei gibt es keine leere Zeilen in der Datei! Schöne Endlosschleife aber mehr auch nicht... :(
       }
       myFile.close();
    }
    

    Einfache Frage: Was muss ich wo wie abändern damit das funktioniert?

    Schonmal danke im Voraus! 🙂



  • maSu schrieb:

    Moin, einfaches Problem - eigentlich, ich finde dazu vieles im Netz aber nichts was so richtig will.

    Ich habe mittels ifstream eine xml-Datei ausgelesen, alles lief wunderbar. Dann fiel mir auf, dass da div. Zeichen drinstehen, die der normale string nicht kann, also habe ich alles auf wstring umgestellt und aus dem ifstream ein wifstream gemacht.

    .. und damit wahrscheinlich schon einen kapitalen Fehler gemacht.

    Öffne doch mal Deine XML-Datei mit einem einfachen Texteditor. Dann steht oben wahrscheinlich so was wie

    <?xml version="1.0" encoding="UTF-8" ...
    

    Wenn Du jetzt dafür einen wifstream benutzt, musst Du dem Stream noch sagen, dass er alles mit encoding="UTF-8" lesen soll. Dazu ruft man die Methode imbue mit einer passenden Facette auf.
    Seit C++11 gibt es das auch im Standard: siehe codecvt_utf8

    Gruß
    Werner

    PS.: getline ist zum Lesen einer XML-Datei ziemlich ungeeignet



  • Bei mir klappt übrigens alles...



  • Jup es ist utf8...

    Zu Imbue:

    http://www.cplusplus.com/reference/codecvt/codecvt_utf8/?kw=codecvt_utf8

    Das habe ich dazu gefunden, dachte mir "ja Mensch, ist ja einfach, tippst es einfach mal ab!". Es scheitert allerdings schon am #include <codecvt>, da diese Headerdatei auf dem System nicht verfügbar ist.

    Gibt es noch andere Möglichkeiten zum einlesen von ganzen Zeilen?
    Nur für den Fall, dass es mit wifstream auf dem *böses adjektiv deiner Wahl* Testsystem mit wifstream nicht realisierbar ist.

    Wollte eigentlich eine Lösung mittels Qt vermeiden um möglichst unabhängig zu sein, aber was solls, hier meine Lösung, falls es jemanden interessiert:

    QString qstrBuffer;
    QFile qmyFile("Pfad und Dateiname hier einfügen");
    if(!myqFile.open(QIODevice::ReadOnly | QIODevice::Text)
       return ERROR;
    QTextStream qmyStream(&myqFile);
    qmyStream.setCodec("UTF-8");
    qstrBuffer=qmyStream.readline();
    while(!strqBuffer.isNull())
    {
       //hab spaß mit dem Text
       //nächste Zeile lesen
       qstrBuffer=qmyStream.readLine();
    }
    

    Fazit: das funktioniert einwandfrei. Da ich auf dem System ohnehin absolut immer auf die QT Bibliotheken zugriff habe, ist das quasi ein Workaround, aber auch einer, der mich zugegebener Maßen stört. Fürs Erste muss das so laufen, aber ich halte mal die Augen offen ob man das mit wifStream (der mir btw. deutlich besser gefällt!) nicht auch irgendwie hinbekommt - auf anderem Wege dann.

    So und nun noch eine Frage in eigener Sache: Warum ist es nicht gut, xml Dateien Zeilenweise auszulesen? Welche Alternativen existieren und warum sind die besser?



  • maSu schrieb:

    Es scheitert allerdings schon am #include <codecvt>, da diese Headerdatei auf dem System nicht verfügbar ist.

    wahrscheinlich weil Deine Entwicklungsumgebung (noch) kein C++11 kann.
    Alternative ist die Facette boost.utf8_codecvt_facet zu benutzen - findest Du in boost unter boost/filesystem/detail/utf8_codecvt_facet.hpp.

    maSu schrieb:

    Gibt es noch andere Möglichkeiten zum einlesen von ganzen Zeilen?

    wenn Du Zeilen lesen willst, so geht das mit getline, aber was machst Du mit Zeilen aus einer XML-Datei?

    Gruß
    Werner



  • Was ich mit den Zeilen aus der XML-Datei mache: Nach den Tags abfragen und wegsortieren. Für sinnvoller Auslesemöglichkeiten bin ich immer offen 🙂



  • Wenn du sowieso Qt nimmst, warum dann nicht gleich die dort angebotenen Klassen wie z. Bsp. QXmlStreamReader?



  • Jetzt brauche ich einen Facepalm-Smiley für mich selbst... stimmt. Muss mir das morgen mal in Ruhe angucken.

    //Edit:

    danke an alle für die Hilfe!

    Habe jetzt genug Möglichkeiten die Datei (mit oder ohne QT) auszulesen. Habe mich der Einfachheit halber dann aber an den QXmlStreamReader gehalten - geniales Ding, super einfach, schnell ... achje, gut das ich das nicht mehr zu Fuß machen muss 🙂


Anmelden zum Antworten