string aus Datei wird bei cout verschluckt / überschrieben



  • 314159265358979 schrieb:

    Beim Einlesen werden alle Leerzeichen, Newlines, Tabulatoren u.ä. übersprungen.

    Deine Lösung ist natürlich genial - allerdings werden in Zukunft wohl auch Strings mit Leerzeichen ausgelesen werden müssen (z.B. "Grüner Drache" 😉 ). Wie ließe sich das bewerkstellen, geht das irgendwie auch mit der supereleganten RAII-Methode?



  • Dann nimmst du einfach für den ersten String getline() und danach für die beiden ints den operator >>. 😉

    RAII ist übrigens ein allgemeines Konzept. Fall du es noch nicht kennst, solltest du es dir ansehen: http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization


  • Mod

    thuering schrieb:

    314159265358979 schrieb:

    Beim Einlesen werden alle Leerzeichen, Newlines, Tabulatoren u.ä. übersprungen.

    Deine Lösung ist natürlich genial - allerdings werden in Zukunft wohl auch Strings mit Leerzeichen ausgelesen werden müssen (z.B. "Grüner Drache" 😉 ). Wie ließe sich das bewerkstellen, geht das irgendwie auch mit der supereleganten RAII-Methode?

    Dafür haut mich volkard bestimmt:

    ifstream datei("Monster.chr");
    
        string MonsterName;
        int MonsterTP, MonsterIniMod;
        getline(datei, MonsterName) >> MonsterTP >> MonsterIniMod;
    

    Es wird geringfügig komplizierter, falls danach noch weitere getlines folgen, weil die dann denken, dass die Zeile sofort endet, da das letzte >> ein Zeilenendzeichen im Stream lässt.



  • Dann habe ich wieder das Problem des verschwindenden Strings bei der Ausgabe - s.o.
    Mit welchem String-Operator kann ich denn effektiv die letzten beiden Zeichen "\r" löschen? Oder gibt es vllt. die Möglichkeit, mit einem geeigneten Text-Editor (ich habe hier Notepad++) das \r zu löschen?



  • Vielen Dank ihr Beiden, die Sache läuft nun rund!
    Ich habe es jetzt mal mit 2 Strings hintereinander versucht, diese Lösung hier liefert alle Ergebnisse einwandfrei:

    string MonsterName, MonsterRasse;
        int MonsterTP, MonsterIniMod;
        getline(datei, MonsterName);
    	getline(datei, MonsterRasse) >> MonsterTP >> MonsterIniMod;
    

    Wenn ich es so mache, dann wird bei "Gruener Drache" das "Drache" bei der Ausgabe per cout "verschluckt":

    string MonsterName, MonsterRasse;
        int MonsterTP, MonsterIniMod;
        getline(datei, MonsterName) >> MonsterRasse >> MonsterTP >> MonsterIniMod;
    

    Ist das erklärbar oder handelt es sich hier tatsächlich um einen "Bug"?

    Achja, Inhalt der ausgelesenen Datei:

    Tharaxyxyl
    Gruener Drache
    100
    10
    

  • Mod

    Ist das erklärbar oder handelt es sich hier tatsächlich um einen "Bug"?

    Nein, das ist dann ganz normal. Oben hast du eine ganz andere Datei gepostet, der Einlesevorgang den ich dir geschreiben habe passt zu deren Format, nicht zu dem neuen. Verstehe was du tust und schreib nicht blind ab!



  • Das "Drache" wird nicht bei cout geschluckt, sondern einfach nicht mit eingelesen, weil der Input-Operator alle Whitespaces als Eingabeende betrachtet.



  • SeppJ schrieb:

    Ist das erklärbar oder handelt es sich hier tatsächlich um einen "Bug"?

    Nein, das ist dann ganz normal. Oben hast du eine ganz andere Datei gepostet, der Einlesevorgang den ich dir geschreiben habe passt zu deren Format, nicht zu dem neuen. Verstehe was du tust und schreib nicht blind ab!

    Du hast natürlich Recht, aber erstmal eine Referenz finden, die solch ein Konstrukt erklärt... In meinen Büchern steht zu deiner (sehr gut funktionierenden) Methode nichts, in meinen Videotutorials auch nicht und auch über Google habe ich nichts vergleichbares gefunden. Ich finde immer nur Beispiele vor, in denen ein Char-Array gefüllt wird oder ein einzelner String ausgelesen wird.



  • thuering schrieb:

    [...] Videotutorials [...]

    NICHT (!!) ansehen.


  • Mod

    Das Geheimnis ist, dass sämtliche Eingaben (und ausgaben übrigens auch) auf Streams den Stream selbst zurückgeben. Dadurch kann man überhaupt Konstrukte in der Form cout << a << b << c; bzw. cin >> a >> b >> c; schreiben. Das ist aber nicht auf die Operatoren >> und << beschränkt, sondern funktioniert auch hervorragend mit getline.



  • Weitere Frage zu dem Thema:
    Wie lese ich eine bestimmte Zeile (anhand Zeilennummer) aus?
    Soll ich mir da eine for-Schleife basteln, die alle Überflüssigen Lines in einen Dummy-String schreibt, um dann an der richtigen Adresse zu lesen?
    Oder gibts da andere tolle Lösungen?

    Swordfish schrieb:

    thuering schrieb:

    [...] Videotutorials [...]

    NICHT (!!) ansehen.

    OK. Auch nicht die teuer gekauften von Video2Brain oder Galileo? 🙄



  • Gezielt eine bestimmte Zeile anzusprechen geht nur, wenn du vorher schonmal die komplette Datei eingelesen hast (immer abwechselnd per getline() einlesen und per seekg() die Position mitschreiben - später kannst du dann per tellg() dorthin zurückspringen).


Anmelden zum Antworten