Leere Zeilen am Ende einer Textdatei löschen



  • Moin beisammen

    Also ich habe folgendes Probleme:
    Ich habe eine Textdatei die einige Zeilen Text enthält. Sie sieht beispielsweise so aus:

    Zeile 1
    Zeile 2
    Zeile 3
    
    Zeile 4
    Zeile 5
    Zeile 6
    
    Zeile 7
    Zeile 8
    Zeile 9
    .
    .
    .
    

    Die drei Zeilen mit Punkten unter Zeile 9 sollen nur leere Zeilen darstellen, wie diese zwischen Zeile 3 und 4 und Zeile 6 und 7. (Forum-Formatierung zeigt leere Zeilen am Ende sonst net an, deshalb die Punkte ;))

    So, ich möchte jetzt mit einer C++-Routine (das ganze spielt sich übrigens in einer MFC-Anwendung ab) die leeren Zeilen hinter Zeile 9 löschen. Ich bin nicht unerfahren, also ich weiß schon wie das prinzipiell funktionieren würde.

    Leider habe ich nur eine umständliche Idee. Ich würde also mit CStdioFile, mit dem ich arbeite, die Datei durchrasseln. Sobald die letzte Zeile mit richtigen Textzeichen gefunden wurde, merkt er sich, die wievielte Zeile das war und schaut dann wieviele Zeilen noch kommen. Danach würde er die Datei noch einmal durchlaufen und ab der gemerkten Zeile die folgenden nicht mehr übernehmen.

    Das kostet nun in der heutigen Zeit zwar nicht all zu viel Perfomance, trotzdem erscheint es mir irgendwie nicht die sauberste oder eleganteste Lösung zu sein.

    Deshalb stelle ich die Frage hier jetzt einfach mal in den Raum, vielleicht hat an der Aufgabe ja jemand Spaß und ihm fehlt eine bessere Lösung ein.

    Gruß, Kane



  • Nur mla noch schnell ne andere Frage, kannst evtl. noch sagen wieso da 3 leere Zeile in der Datei unten sind?

    Gruß Tobi.



  • Du könntest in der Datei rückwärts suchen, bis du ein Zeichen findest …



  • Hi,

    ich würde das ganze ungefähr so machen.
    Hab jetz nur die STL verwendet, wenn du willst kannst du den Code aber sicher auch in die MFC übertragen.

    🙂

    #include <string>
    #include <fstream>
    using namespace std;
    
    int main()
    {   
    	// Datei
    	const char* file = "text.txt";
    
    	// Datei zum Lesen öffnen
    	ifstream ifile(file, std::ios_base::binary);
    	if(!ifile.good())
    		return 1;
    
    	// Länge der Datei herausfinden
    	ifile.seekg(0, std::ios_base::end);
    	size_t fsize = ifile.tellg();
    	ifile.seekg(0, std::ios_base::beg);
    
    	// Buffer reservieren
    	char *ibuffer = new char[fsize+1];
    
    	// Datei komplett einlesen
    	ifile.read(ibuffer, (int)fsize);
    	ibuffer[fsize] = '\0';
    
    	// Das ganze in einen std::string kopieren und Buffer wieder löschen
    	string str = ibuffer;
    	delete [] ibuffer;
    
    	// Alle newline Characters am Ende des Strings abschneiden
    	size_t f = str.length()-1;
    	while(str[f] == '\n' || str[f] == '\r'){
    		str.erase(f, 1);
    		f = str.length()-1;
    	}
    
    	// Datei schließen
    	ifile.close();
    
    	// Datei zum Schreiben öffnen
    	ofstream ofile(file, std::ios_base::binary);
    	if(!ofile.good())
    		return 1;
    
    	// String hinein schreiben
    	ofile.write(str.c_str(), (int)str.length());
    
    	// Datei schließen
    	ofile.close();
    
    	return 0;
    }
    


  • T0bi schrieb:

    Nur mla noch schnell ne andere Frage, kannst evtl. noch sagen wieso da 3 leere Zeile in der Datei unten sind?

    Gruß Tobi.

    Selbstverständlich. Ich downloade eine HTML Datei von Dark-Lyrics. In dieser sind halt immer in sehr ähnlicher Formatierung die Lyrics zu einem Album. Mein Programm erstellt dann daraus die Lyrics als einzelne txt-Dateien. Dabei bleiben die <br> natürlich erstmal stehen. Sobald ich diese nun lösche, habe ich am Ende der Lyrics immer noch ein paar <br> die dann zu leeren Zeilen führen.

    .filmor schrieb:

    Du könntest in der Datei rückwärts suchen, bis du ein Zeichen findest …

    Wie durchsuchen ich denn eine Datei mit CStdioFile rückwärts?

    JustSomeCoder schrieb:

    Hi,

    ich würde das ganze ungefähr so machen.
    Hab jetz nur die STL verwendet, wenn du willst kannst du den Code aber sicher auch in die MFC übertragen.

    Dein Ansatz gefällt mir wirklich gut. Ich bin nur nicht ganz sicher, ob ich dsa so auf CStrings und CStdioFile übertragen kann. Ich werde das ganze aber mal sofort ausprobieren. Danke dir auf jeden Fall schonmal!



  • So wie eine trim()-Funktion:

    In den Speicher laden
    von hinten solange 0 reinschreiben bis die Speicherzelle > SPACE ist
    fertig

    Dir Stringlänge ergibt sich dann mit strlen().


Anmelden zum Antworten