Streams mit größeren Dateien



  • Hallo erstmal,

    ich hab mal wieder ein Problem. Ich habe ein einfaches Programm geschrieben, dass nach einer Zeile in einer Datei sucht und darüber dann einen Text aus einer anderen Datei schreibt, das ganze wird dann in einer dritten Datei (hier: new.txt) gespeichert.
    Das klappt soweit auch ganz prima, bei kleineren Dateien von ein paar Kilobytes zumindest. Nehme ich nun aber als erste Datei (die Datei in der gesucht wird und deren Text zusammen mit dem Eingefügten in die new.txt geschrieben wird) eine größere (habs mal mit ca. 400 kb versucht, das war schon zu viel, ich weiß nicht genau ab welcher Größe), dann werden ab einem bestimmten Punkt unendlich viele Leerzeilen eingefügt, sodass die new.txt, nachdem ich das Programm abbreche, größer ist als die Dateien mit dem Ausgangstext und dem Eingefügten zusammen.
    Das Komische ist, dass nicht etwa ab der eingefügten Stelle die Leerzeilen anfangen, sonst könnte es ein Fehler im Programm sein. Hier mein Code:

    #include <iostream>
    #include <fstream>
    #include <windows.h>
    
    using namespace std;
    
    int main()
    {
    cout<<"Gebe hier die Datei an:\n";
    string file;
    cin>>file;
    
    cout<<"\n\nGebe nun die Datei mit dem Script an!\n";
    string script;
    cin>>script;
    
        fstream f;
        fstream h;
    
        fstream intof;
        intof.open("new.txt", ios::out);
    
        char cstring[256];
        char ofh[256];
        f.open(file.c_str(), ios::in);
        h.open(script.c_str(), ios::in);
        int once = 0;
        while (!f.eof())
        {
            f.getline(cstring, sizeof(cstring));
            string x = cstring;
    
            if (x == "blablubb") {
    
                  if (once == 0) {
                           intof<<endl;
                  }
    
                  while(!h.eof()) {
                      h.getline(ofh,sizeof(ofh));
                      string y = ofh;
    
    //                  intof << x << endl;
                      intof << y << endl;
    
                  }
                  intof<<endl<<endl<<endl;
            }
    
            intof << x << endl;
    
        }
        f.close();
        intof.close();
        h.close();
    
        system("PAUSE");
    
    }
    

    Das geht bestimmt auch irgendwie kürzer, ist mir aber um ehrlich zu sein ziemlich egal.

    Woher kommen diese Leerzeilen und wie schaffe ichs, dass sie nichtmehr auftauchen?

    mfG Alemarius Nexus



  • das der Code jemals funktioniert grenzt an einem wunder...

    Erklär mal mit einem Beispiel was du genau machen willst ... dein Code ist einfach unübersichtlich und was glaubst du was sizeof(array) dir zurück gibt?



  • was glaubst du was sizeof(array) dir zurück gibt?

    Das weiß ich nicht, muss ich zugeben. den Code für die Streams hab ich aus dem Internet übernommen und weil er funktioniert hat, hab ich mir darüber eigentlich keine Gedanken gemacht (nein, ich habe NICHT das ganze Programm übernommen). Aber soweit ich weiß, gibt einem das die Größe aller Arrayelemente zusammen zurück.
    Aber weil das ja bisher und auch hier mit kleineren Dateien geklappt hat, müsste das ja gehen.

    Das Programm öffnet zwei eingegebene Dateien zum Lesen (die, in der der Grundtext steht und die mit dem, was zwischen den Grundtext eingefügt werden soll) und eine zum Schreiben (hier: new.txt, dort wird dann der Grundtext und das Eingefügte reingeschrieben). Dann wird der Grundtext solange in die new.txt geschrieben, bis der Text 'blablubb' gefunden wurde. Dann wird erstmal über diese Zeile mit 'blablubb' das Einzufügende aus der zweiten Datei geschrieben, danach wird der Grundtext weiter abgerattert. Ein Beispiel:

    Grundtextdatei (erste Datei):

    Ich
    sage
    blablubb
    und so weiter
    und so fort

    Einzufügendes (zweite Datei):

    nicht

    am Ende steht in der new.txt (dritte Datei) also folgendes:

    Ich
    sage
    nicht
    blablubb
    und so weiter
    und so fort

    (ein bescheuertes Beispiel, ich weiß, aber ich musste erstmal einen logischen Text finden, der auf den Suchtext 'blablubb' passt 😃 )



  • Alemarius Nexus schrieb:

    int once = 0;
    /*  while (!f.eof())
        {
            f.getline(cstring, sizeof(cstring));
            string x = cstring;
            
            if (x == "blablubb") {
                  
                  */
                  if (once == 0) {
                           intof<<endl;
                  }
    

    Was für ein Sinn macht denn ein int once = 0 und die anschließende if Bedingung if(once ==0)?
    Du initialisierst once ein mal mit 0 und das wars.
    Also unnötig diese Abfrage auch wenn ich nicht nachvollziehen kann was du überhaupt mit once anstellen möchtest.



  • Wirf erstmal die char-Arrays raus und nimm statt dessen string. Das dürfte ein Gutteil deiner Probleme beheben.
    Wegen once, das sollte wohl eher so aussehen.

    if (once == 0) 
    {
       intof<<endl;
       once = 1;
    }
    

    Deine wechselnden Einrückungen sowie die vielen Leerzeilen im Code machen den nicht wirklich lesbarer. 🙂



  • Nja ... woher weiß du denn an welche Stelle der String soll?

    bool file_merge_content(const std::string& file_merge, const std::string& file_source, const std::streamsize& pos, const std::string& file_dest)
    {
    	std::fstream file_stream(file_source.c_str(), std::ios::in);
    	if (!file_stream)
    		return false;
    	/* Einzufügenden Text aus Datei auslesen */
    	std::string insert_total;
    	std::string temp_line;
    	while (std::getline(file_stream, temp_line))
    		insert_total += (temp_line + '\n');
    
    	file_stream.close();
    	file_stream.clear();
    
    	file_stream.open(file_merge.c_str(), std::ios::in);
    	if (!file_stream)
    		return false;
    
    	/* Zeilenweise einlesen. Wenn wir an der Stelle sind wo du es eingefügt haben willst, erst einfügen. */
    	std::string final_content;
    	for (std::streamsize line = 0; std::getline(file_stream, temp_line); ++line)
    	{
    		if (line == pos)
    			final_content += insert_total;
    		final_content += (temp_line + '\n');
    	}
    
    	file_stream.close();
    	file_stream.clear();
    
    	/* Unseren zusammengesetzten Inhalt wieder in eine Datei packen. */
    	file_stream.open(file_dest.c_str(), std::ios::out);
    	if (!file_stream)
    		return false;
    
    	file_stream << final_content << std::endl;
    	return true;
    }
    

    wäre wohl eine saubere Lösung 🙂

    EDIT
    Erklärung hinzugefügt.



  • Braunstein schrieb:

    Wirf erstmal die char-Arrays raus und nimm statt dessen string. Das dürfte ein Gutteil deiner Probleme beheben.

    das würde ich auch empfehlen. Ich kann aber in obigen Code keinen Fehler feststellen, der zum beschriebenen Verhalten führt.

    @Alemarius: versuch' es mal hiermit und berichte von Deinen Erfahrungen.

    #include <iostream>
    #include <fstream>
    #include <string>   // .. fehlte
    #include <windows.h>
    
    using namespace std;
    
    int main()
    {
        cout<<"Gebe hier die Datei an:\n";
        string file;
        cin>>file;
    
        cout<<"\n\nGebe nun die Datei mit dem Script an!\n";
        string script;
        cin>>script;
    
        ofstream intof( "new.txt" );
        ifstream f( file.c_str() );
        for( string x; getline( f, x ); )
        {
            if (x == "blablubb") {
                intof<<endl;
                // hier jetzt Inhalt aus 'script' einfügen
                ifstream h( script.c_str() );
                intof << h.rdbuf();
    
                intof << endl << endl << endl;  // + 3 Leerzeilen
            }
            intof << x << endl;
        }
        system("PAUSE");
    }
    

    Gruß
    Werner



  • @ (D)Evil:

    Hab ich jetzt nicht benutzt, weil Werners kürzer ist, trotzdem danke.

    Was für ein Sinn macht denn ein int once = 0 und die anschließende if Bedingung if(once ==0)?
    Du initialisierst once ein mal mit 0 und das wars.

    Huch, hab ganz vergessen once danach zu 1 zu machen, ich hab den Code mehrmals geändert, deshalb macht es jetzt bei genauer Betrachtung garkeinen Sinn mehr. 🤡

    @Werner Salomon:

    Ich hab jetzt deine Variante genommen, danke dafür.

    Klappt jetzt wunderbar, und wieder mal danke an alle 😉


Anmelden zum Antworten