fstream - verweigert das schreiben ins Dokument



  • Einen schönen guten Tag wünsche ich :),
    ich habe jetzt vor kurzem mit dem Lernen von C++ begonnen. Bis dahin habe ich größten Teils in Java programmiert. Während meiner Nachforschungen bin ich auf dieses Forum gestoßen, das mir bereits (mithilfe der SuFu ;)) häufig weiter geholfen hat ;). Dafür schonmal ein Danke an alle Beiträge, die ich bislang gelesen habe ;). Jetzt habe ich aber momentan ein Problem, bei dem ich einfach nicht weiter komme. Ich vermute es liegt an einem Verständnisproblem ;). Ich hoffe jemanden fällt ein Fehler auf und kann mir den richtigen Denkanstoß geben ;). Aber nun zu meinem Problem:

    Ich möchte gerne in eine bereits bestehende Datei Ergänzungen hinzufügen, die
    aber innerhalb des Dokuments und nicht am Ende angehängt werden sollen.
    Also habe ich folgender maßen begonnen:

    void addElement(string path, string element){
    string keyWord;
    bool posFound == false;
    fstream environment;
    environment.open(path,ios::out|ios::in)
    

    Also bis hierhin öffne ich einfach mein Dokument und erlaube sowohl das Lesen, wie auch das Schreiben. In meinem Buch stand, dass wenn ios::out benutzt wird, ios::in folgen muss, damit der Inhalt nicht gelöscht wird.
    Also weiter

    while(!environment.eof() && !posFound){  
        getLine(environment,keyWord)
        if (keyWord == "addHere")
          posFound = true;
      }
    

    Mit dem Code-Abschnitt spring ich in die Zeile, in der das neue Element stehen soll. Bis hierhin habe ich noch die Hoffnung, dass alles funktioniert. Und nun zu der kritischen Stelle.

    environment << "\n\t\t" << element << "\n";
    }
    

    Hier sollte er eigentlich den Inhalt von element, in das Dokument an die Stelle schreiben an die ich im vorherigen Abschnitt gesprungen bin. Nur leider bleibt man Dokument, wenn ich es mir ansehe, unverändert. Was läuft da falsch bzw. was ich habe da noch nicht verstanden?
    Hier noch die verwendeten #includes:

    #include <fstream>
    #include <iostream>
    #include <string>
    using namespace std;
    

    Fall es weiterhelfen sollte: Ich nutze zum programmieren viusal studios 2010.
    Ich hoffe jemand kann mir hier helfen 😞 . Ich bedanke mich auf jeden Fall mal schon für die Mühe :).
    Gruß



  • Aeron schrieb:

    Ich möchte gerne in eine bereits bestehende Datei Ergänzungen hinzufügen, die aber innerhalb des Dokuments und nicht am Ende angehängt werden sollen.

    Kurz und knapp: Das ist nicht möglich.

    hustbaer schrieb:

    Du kannst an Dateien immer nur hinten was anhängen. Vorne anhängen geht nicht. In der Mitte einfügen geht auch nicht.
    D.h. du musst den gesamten Inhalt der Datei umkopieren.



  • Vielen Dank für die super schnelle Antwort :). Da hätte ich dann ja noch lange herum probieren können.
    Dann werde ich gleich mal probieren, das Dokument einfach zu kopieren mit dem neuen Inhalt ;). Mein Dokument wird zwar wahrscheinlich nie wirklich lang, aber gibt es effizientere Möglichkeit als das Kopieren?
    Auf jeden Fall vielen Dank 😉 !



  • Du kannst noch versuchen, unmittelbar vor dem Schreiben ein

    environment.seekp( environment.tellg() ); // setzt den Schreibzeiger auf die aktuelle Leseposition
    

    zu setzen

    Der Effekt ist dann, dass das File überschrieben wird, d.h. schreibst Du weniger als schon hinter der Stelle im File steht, so bleibt dieser Inhalt erhalten.



  • Versuch das mal:

    #include <fstream>
    #include <iostream>
    #include <iterator>
    #include <string>
    using namespace std;
    
    void add_element( const string& path, const string& element ) // Schau dir mal call-by-reference an
    {
    	string content;
    	{
    		ifstream environment( path.c_str() ); // Versuch, entweder ifstream oder ofstream zu verwenden, und nicht fstream
    		content = string( (istreambuf_iterator<char>(environment)), (istreambuf_iterator<char>()) );
    	}
    
    	string keyword    = "addHere";
    	unsigned position = content.find( keyword );
    	if( position != std::string::npos )
    	{
    		string insert = "\n\t\t" + element + '\n';
    		content.replace( position, keyword.length(), insert );
    	}
    
    	ofstream environment( path.c_str() );
    	environment << content;
    }
    
    int main()
    {
    	add_element( "test.txt", "DAS IST NEU" ); // Hallo welt, addHere wie geht es dir heute?
    }
    


  • Vielen vielen Dank für die ganzen Tipps und die super schnelle Hilfe :). Ich werde versuchen mir die Sachen jetzt nochmal in ruhe anzugucken und nachzuvollziehen und werde es dann nocheinmal selbst versuchen zu programmieren :). Ihr habt mir super weitergeholfen :). Danke :)!!!


  • Mod

    Aeron schrieb:

    Mein Dokument wird zwar wahrscheinlich nie wirklich lang, aber gibt es effizientere Möglichkeit als das Kopieren?

    Wenn wirklich eingefügt werden muss: Nein. Aber es wäre eine Idee, sich ein Format zu überlegen, bei dem man Änderungen auch anhängen kann oder die Änderungen separat speichert oder die Reihenfolge in der Datei von vornherein keine Rolle spielt.

    So machen (oder machten? Ich bin da nicht so auf dem Stand) das zum Beispiel viele Büroprogramme, um Dateien schneller zu speichern*.

    *: Übrigens ein riesiges Sicherheitsloch, wenn man etwas löscht und das Dokument dann verschickt. Dann kann jeder die Änderungen rückgängig machen.



  • Als Übung hatte ich mir halt überlegt, sowas ähnliches wie eine xml Struktur zu schreiben. Und die sind ja aufgebaut wie so eine Baumstruktur, in die ja sicherlich nicht immer nur am Ende eingefügt wird. Deswegen dachte ich mir, dass wäre möglich einfach irgendwie dazwischen was zu ergänzen. Aber wie gesagt, ich probier mal die Sachen von out und Werne_logoff aus. Würde ich gerne sofort angehen, muss aber leider gleich zur Arbeit 🙄 .



  • hey, seh den post zwar leider etwas spät, aber wäre es nicht auch eine möglichkeit die datei erstmal komplett einzulesen, dann zeile für zurückschreiben und auf die gesuchte Position zu prüfen??Hab mir irgendwas wie dies hier gedacht

    [code="cpp"]
    std::ifstream File("test.cpp"); //Datei öffnen und auf fehler prüfen
    if(File == NULL)
    return 1;
    std::string element("found"); //Die neu zu schreibende zeile
    std::string Lines; //Die einzelnen Zeilen der datei
    std::vectorstd::string FileLines; //Vector mit den zeilen
    while(!File.eof()){
    getline(File,Lines); //Einlesen der datei
    FileLines.push_back(Lines);
    }
    std::ofstream NewFile("test.cpp", std::ios_base::trunc); //Die neue datei
    for(auto i : FileLines){
    if(i.find("addhere") == std::string::npos) //gefunden?
    NewFile << i << std::endl; //schreibe lediglich nächste zeile
    else{
    NewFile << element << std::endl; //schreibe unsere zeile vor die alte zeile
    NewFile << i << std::endl;
    }
    }
    }
    [code="cpp"]

    Naja war nur ein gedanke vllt hilft es ja irgendwie



  • negaduck schrieb:

    aber wäre es nicht auch eine möglichkeit die datei erstmal komplett einzulesen, dann zeile für zurückschreiben und auf die gesuchte Position zu prüfen?

    Geht auch. Aber nicht mit deinem Quellcode. 😃



  • Ohh erstmal sorry dafür das die CodeTags nicht funzten.
    Hmm bei mir hat der Code ohne Probleme funktioniert fehlen natürlich nur die main und die Header.Wärst du vllt so freundlich dein Wissen mit uns(bzw. mir) nicht wissenden zu teilen??


Anmelden zum Antworten