istream::getline() in Verbindung mit istream::operator<<



  • Hallo zusammen,

    ich bastele immer noch an bestimmten Dateilese- (und -schreib-) routinen herum.

    Ich schreibe bestimmte Angaben in eine Datei und lese diese sukzessive aus.
    Bisher verwende ich dabei als Datentypen nur Zahlentypen (int, unsigned short) und Einzel-Chars, getrennt durch Semikola. Das funktioniert recht gut:

    const char trz = ';';
    
    int meineklasse::ausgelesen(istream& lies) {
    
    	int wert1;
    	char z;
    	lies >> wert1 >> z;
    	if (z != trz || !lies.good()) { return 1;}
    	double wert2;
    	lies >> wert2 >> z;
    	if (z != trz || !lies.good()) { return 1;}
            // ...
            return 0;
    }
    

    Hierbei habe ich festgestellt, dass Zeilenumbrüche keine Rolle spielen, also nicht als Char ausgelesen werden.

    Nun möchte ich zusätzlich aber auch einen std::string auslesen.
    Die gelesene Datei soll nach meinen Vorstellungen folgendermaßen aussehen:

    wert1;wert2; ....
    derAuszuselendeString
    weitere Zeilen

    Mein erster Gedanke war, anstelle der "//..." im Codefragment fortzusetzten mit:

    std::string zeile;
    lies.getline(zeile, ZEILENLAENGE);
    //... verarbeite zeile
    

    Das funktioniert nicht:
    Da ich mit den <<-Operatoren bereits eine vollständige Zeile ausgelesen habe, ergibt dies stets einen Speicherzugriffsfehler (es sei denn, ich definiere ZEILENLAENGE als 0).
    Irgendwie scheint die Kombination von << und getline so nicht möglich zu sein.

    Daher meine Fragen:

    • Wie kann ich einen istream auffordern, einen Zeilenumbruch zu "lesen", d.h.
      "lies das nächste Zeichen, einschließlich Steuerzeichen"?
    • Wie kann ich eine istream auffordern, am Anfang der nächsten Zeile weiterzulesen?
    • Weiterlesen am Anfang der nächsten Zeile wie eben, aber unter Sicherung des übersprungenen Zeilenendstücks (d.h. gibt es eine Funktion wie istream::getRestOfLine())?

    Vielleicht gibt es ja auch eine andere Möglichkeit, einen String unbekannter Länge bequem auszulesen. Ich dachte jedoch, dass ein Zeilenumbruch schon ein günstiges Trennzeichen ist.


  • Mod

    Alle deine Fragen erübrigen sich mehr oder weniger, denn du benutzt deine Strings wie char-Arrays, die sie nicht sind:
    http://www.cplusplus.com/reference/string/
    Insbesondere kommen sie mit einem eigenen getline (siehe Link).

    Wie kann ich einen istream auffordern, einen Zeilenumbruch zu "lesen", d.h.
    "lies das nächste Zeichen, einschließlich Steuerzeichen"?

    Prinzipiell gar nicht, außer du schreibst es dir selbst. Aber du solltest so etwas gar nicht brauchen.

    Wie kann ich eine istream auffordern, am Anfang der nächsten Zeile weiterzulesen?

    Alles bis zum Anfang der nächsten Zeile ignorieren:
    http://www.cplusplus.com/reference/iostream/istream/ignore/

    Weiterlesen am Anfang der nächsten Zeile wie eben, aber unter Sicherung des übersprungenen Zeilenendstücks (d.h. gibt es eine Funktion wie istream::getRestOfLine())?

    😕 Was möchtest du? Gib mal ein Beipiel. Wenn du bis zum Ende der Zeile lesen möchtest, kannst du doch getline nehmen!



  • Alles klar. istream::ignore springt zum nähchsten Zeilenanfang,
    getline muss ich als getline(istream, string) aufrufen, und es liest den Rest der Zeile (ab aktueller Position).
    Mein eigentliches Problem war also (wie ich jetzt weiß), dass ich mit den alten C-Stings nicht gut umgehen kann (aber auch nicht mehr muss).

    Das ist schon alles was ich brauchte!
    Vielen Dank für die Hilfe.


Log in to reply