Dateizeiger nutzen



  • Hallo an die Experten,
    in meinem fortgeschrittenen Alter nutze ich das Programmieren, um meinen Kopf fit zu halten. Ich habe, dank Internet, schon einiges von C++ gelernt und auch einige Programme fuer mich geschrieben.
    Bei dem Arbeiten mit Dateien komme ich aber mit dem Management der Dateizeiger nicht so richtig weiter.
    Mein Problem: ich moechte eine existierende Datei beschreiben und die vorhandenen Daten erhalten. Also oeffne ich die Datei mit ios::app. Soweit ich es verstehe, ist der Dateizeiger dann Null. Damit kann ich nicht um eine definierte Zahl von Bytes zurueckgehen. Gibt es eine Lösung dafuer?
    Anbei ein Beispiel. Dies funktioniert, wenn ich die Datei beschreibe, dann zueckspringe und wieder schreibe. Schliesse ich aber die Datei und oeffne sie wieder, kann ich den Dateizeiger nicht rueckwaerts manipolieren. Oder?

    Beispiel:

    // position of put pointer
    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <string.h>
    using namespace std;

    int main () {
    long pos, pos1;
    string zeile[200];
    ofstream iofile;
    iofile.open ("test.txt", ios::in | ios::out);
    //
    iofile << "Erste Zeile \n";
    iofile << "Zweite Zeile \n";
    iofile << "This is an apple\n";
    iofile << "ende\n";
    iofile.seekg();
    pos1=iofile.tellp(); cout <<" Pos1 ist " << pos1 << "\n";
    iofile >> zeile;
    // outfile.close();
    // hier koennen noch Programmaschritte ausgefuehrt weren
    // outfile.open ("test.txt", ios::out|ios::app);
    // pos=outfile.tellp(); cout <<" Pos2 ist " << pos << "\n";
    // outfile.seekp(pos1);
    // pos=outfile.tellp(); cout <<" Pos3 ist " << pos << "\n";
    // werden die Zeilen 22 bis 27 als Kommentar gekennzeichnet ist alles ok
    outfile.seekp (pos1-15);
    //
    pos1=outfile.tellp(); cout <<" Pos4 ist " << pos1 << "\n";
    outfile << " sam";
    //
    outfile.close();
    //
    return 0;
    }
    Wird das Programm so ausgefuehrt, ist die Manipulation des Zeigers ok. Wird die Datei geschlossen und wieder geoeffnet, ist die Manipulation nicht moeglich.
    Gibt es eine Erklaerung und einen workaround?
    MfG hans



  • hjwe schrieb:

    Hallo an die Experten,
    in meinem fortgeschrittenen Alter nutze ich das Programmieren, um meinen Kopf fit zu halten. Ich habe, dank Internet, schon einiges von C++ gelernt und auch einige Programme fuer mich geschrieben.
    Bei dem Arbeiten mit Dateien komme ich aber mit dem Management der Dateizeiger nicht so richtig weiter.
    Mein Problem: ich moechte eine existierende Datei beschreiben und die vorhandenen Daten erhalten. Also oeffne ich die Datei mit ios::app. Soweit ich es verstehe, ist der Dateizeiger dann Null. Damit kann ich nicht um eine definierte Zahl von Bytes zurueckgehen. Gibt es eine Lösung dafuer?
    Anbei ein Beispiel. Dies funktioniert, wenn ich die Datei beschreibe, dann zueckspringe und wieder schreibe. Schliesse ich aber die Datei und oeffne sie wieder, kann ich den Dateizeiger nicht rueckwaerts manipolieren. Oder?

    Beispiel:

    // position of put pointer
    #include <iostream>
    #include <fstream>
    #include <iomanip>
    #include <string.h>
    using namespace std;
    
    int main () {
      long pos, pos1;
      string zeile[200];
      ofstream iofile;
      iofile.open ("test.txt", ios::in | ios::out);
    //
      iofile << "Erste Zeile \n";
      iofile << "Zweite Zeile \n";
      iofile << "This is an apple\n";
      iofile << "ende\n";
      iofile.seekg();
      pos1=iofile.tellp(); cout <<" Pos1 ist " << pos1 << "\n";
      iofile >> zeile;
    //  outfile.close();
    // hier koennen noch Programmaschritte ausgefuehrt weren
    //  outfile.open ("test.txt", ios::out|ios::app);
    //  pos=outfile.tellp(); cout <<" Pos2 ist " << pos << "\n";
    //  outfile.seekp(pos1);
    //  pos=outfile.tellp(); cout <<" Pos3 ist " << pos << "\n";
    //   werden die Zeilen 22 bis 27 als Kommentar gekennzeichnet ist alles ok
      outfile.seekp (pos1-15);
    //
      pos1=outfile.tellp(); cout <<" Pos4 ist " << pos1 << "\n";
      outfile << " sam";
    //
      outfile.close();
    //
      return 0;
    }
    

    Wird das Programm so ausgefuehrt, ist die Manipulation des Zeigers ok. Wird die Datei geschlossen und wieder geoeffnet, ist die Manipulation nicht moeglich.
    Gibt es eine Erklaerung und einen workaround?
    MfG hans

    Hallo Hans,

    Willkommen im C++-Forum.

    In der Zeile 19 rufst Du die Methode seekg() auf einem Objekt vom Typ ofstream (' iofile '). Das 'g' am Ende von ' seekg ' steht für 'get' - d.h. das ist eine Methode die den Lesezeiger beeinflusst, den der ofstream aber gar nicht handeln kann. Ich vermute, dass der Stream dann in den Fehlerzustand geht und danach sind alle Kommandos wirkungslos.
    Das dürfte sich gar nicht übersetzen lassen - welchen Compiler nutzt Du?

    Zu Deiner Frage: wenn Du eine Datei neu beschreibst, wird das Ende des Schreibens auch wieder zum Ende der Datei. Normalerweise macht man das nicht so. Alternativ fügt man hinten an das Ende der Datei etwas hinzu, oder man liest den Inhalt der gesamten Datei in den Speicher, manipuliert diesen und schreibt alles wieder zurück.

    Gruß
    Werner


Anmelden zum Antworten