Textdatei Komma durch Leerzeichen ersetzen



  • Hallo Liebe Community,

    ich habe mal wieder eine Frage zu C++, diesmal auf das Schreiben in eine Datei.

    Ich habe folgenden Code:

    
    int main()
    {//Datei öffnen und verknüpfen mit einem Objekt
    	ifstream myfile("C:\\Users\\PC\\source\\repos\\ConsoleApplication3\\test.txt");
    	string zeile;
    	while (getline(myfile, zeile)) // woher möchte ich die dateien holen, zeile = was möchte ich holen
    	{
    		//Kommas durch Leerzeichen ersetzen, damit c++ automatisch den string zerlegen kann
    		//Zeilen durchlaufen,
    		for (int i = 0; i <= zeile.size(); i++)
    		{
    			//wenn an i-ter Stelle der Zeile "," dann mache leerzeichen
    			if (zeile[i] == ',')
    			{	
    				zeile[i] = ' ';
    			}
    		}
    		//Variablen anlegen für die einzelnen spalten
    		//Zeile muss in STringstream ungewandelt werden, damit mit dieser Zeile, als Puffer gearbeitet werden kann
    		// Die Zeile ohne "," wird gepuffert, damit diese weiterverarbeitet werden kann
    		//Der Zeilenpuffer wird aus der Zeile gebaut
    		stringstream zeilenpuffer (zeile);
    		string a; int b; double c; int d;
    		//Zeilenpuffer auslesen
    		zeilenpuffer >> a >> b >> c >> d;	
    		/* 
    		wie schreibe ich nun die gepufferten Zeilen in die Datei?
    		ofstream myfile;
    		myfile << a << b << c << d;
    		funktioniert nicht.
    		*/
    		myfile.close();
    	}
    }
    

    Hat einer von euch die Idee wie man den zeilenpuffer nachdem er ja sowieso die "," durch " " ersetzt, auch schreibt?

    Macht man das mit Vektoren?
    Irgendwas mit push_back?

    Vielen Dank und beste Grüße!



  • @bthight Du kannst in einer (frei formatierten) Datei keine Zeile durch eine Andere ersetzen.
    Es kann klappen, wenn die alte und neue Zeile dieselbe Länge haben.

    Normalerweise wird eine neue Datei erzeugt, die alte Datei gelöscht und die neue Datei dann umbenannt.



  • OT

    @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    i <= zeile.size()

    Nein, < nicht <=.



  • Du musst den Inhalt der Datei komplett in den Speicher laden. Die notwendigen Ersetzungen vornehmen und dann die Datei mit den veränderten Daten überschreiben.



  • Ok,

    Danke für eure Antworten.

    Kann ich dann einfach eine Neue Textdatei erstellen lassen, als Ausgabe?
    Und in diese Datei Zeile für Zeile schreiben?

    Ich suche einfach nach einer eleganten Art die "," durch " " zu ersetzen.


  • Mod

    This post is deleted!


  • @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Ok,

    Danke für eure Antworten.

    Kann ich dann einfach eine Neue Textdatei erstellen lassen, als Ausgabe?
    Und in diese Datei Zeile für Zeile schreiben?

    Ich suche einfach nach einer eleganten Art die "," durch " " zu ersetzen.

    Du kannst doch den Inhalt auslesen und dann die gleichnamige Datei einfach überschreiben. Du musst keine "zwischendatei" erstellen.

    1. Datei einlesen in den Speicher und schließen
    2. Speicher manipulieren
    3. Datei schreibend öffnen ( Datei ist dann leer ) und mit dem Inhalt aus dem Speicher befüllen

  • Mod

    Vergiss mal Konzepte wie Dateien, und erst recht Zeilen. Dateien kennen keine Zeilen, das ist nur menschliche Interpretation. Und dein eigentliches Problem ist kein Dateiproblem, sondern das Ersetzen von einem Zeichen mit einem anderen, in einer Sequenz von Buchstaben.

    Ersetzen von einem Ding mit einem anderen, kennt C++ schon, nennt sich naheliegenderweise replace. Oder replace_copy, wenn man das Original nicht ändern will/kann. Wir können jeden Stream zu einer Sequenz machen, indem wir ihn in einem stream_iterator wrappen. Das verpasst dem Stream ein Interface, das replace verstehen kann. Oder streambuf_iterator, wenn uns nicht einmal die High-Level Logik der Streams interessiert und wir es dafür flotter haben wollen (wird aber gefährlich, wenn man Zeilenumbrüche ersetzen möchte). Für die Streams cin und cout als Ziel wäre das also:

        #include <iostream>
        #include <algorithm>
        #include <iterator>
        using namespace std;
         
        int main() {
        	replace_copy(istreambuf_iterator<char>(cin),
        	istreambuf_iterator<char>(),
        	ostreambuf_iterator<char>(cout),
        	',', ' '
        	);
        	return 0;
        }
    

    Geht aber genauso für jeden x-beliebigen Dateistream, denn streambuf_iterator interessiert sich nicht für die Details hinter dem Stream.

    Keine Dateien, keine Zeilen, kein Parsen von Werten, kein Schreiben von Werten, kein Laden ganzer Dateien am Stück, keine Vectoren, oder sonstwas. Nur Buchstaben, die von einem Ort zu einem anderen geschaufelt werden, mit jemandem dazwischen, der gewisse Buchstaben ersetzt.



  • @SeppJ Die erste vernünftige Antwort 👍



  • @SeppJ sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Oder replace_c

    Ich werde mir diese Lösung nochmal in mehr Ruhe anschauen müssen, da ich diese Funktionen nie gesehen habe.

    Ich denke die einfachere Lösung wäre es für einen Anfänger wie mich eine neue Datei zu schreiben.

    Ich habe einach eine neue Datei angelegt in der for schleife

    hier ist mein Code der for-Schleife - sehr simpel:

    for (int i = 0; i < zeile.size(); i++)
    
    		{
    			cout << zeile << "\n";
    			Output << zeile << "\n";
    			//wenn an i-ter Stelle der Zeile "," dann mache leerzeichen
    			if (zeile[i] == ',')
    			{	
    				zeile[i] = ' ';
    			}
    			
    		}
    

    die entstehende Output Datei macht 2 Iterationen durch.
    D.h. in der ersten Iteration (wenn man das so nennen darf?) wird das erste "," entfernt, in der zweiten, das zweite.

    Wie schreibe ich denn nur die "saubere" Datei?

    Siehe Output-Datei:

    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf, 234, 23.456, 3455
    sdfdsfdsfsdsdf 234, 23.456, 3455
    sdfdsfdsfsdsdf 234, 23.456, 3455
    sdfdsfdsfsdsdf 234, 23.456, 3455
    sdfdsfdsfsdsdf 234, 23.456, 3455
    sdfdsfdsfsdsdf 234, 23.456, 3455
    sdfdsfdsfsdsdf 234 23.456, 3455
    sdfdsfdsfsdsdf 234 23.456, 3455
    sdfdsfdsfsdsdf 234 23.456, 3455
    sdfdsfdsfsdsdf 234 23.456, 3455
    sdfdsfdsfsdsdf 234 23.456, 3455
    sdfdsfdsfsdsdf 234 23.456, 3455
    sdfdsfdsfsdsdf 234 23.456, 3455
    sdfdsfdsfsdsdf 234 23.456, 3455
    sdfdsfdsfsdsdf 234 23.456 3455
    sdfdsfdsfsdsdf 234 23.456 3455
    sdfdsfdsfsdsdf 234 23.456 3455
    sdfdsfdsfsdsdf 234 23.456 3455
    sdfdsfdsfsdsdf 234 23.456 3455



  • Überlege mal genau, was du da programmiert hast!?
    Du gibt bisher je Zeichen jedesmal die ganze Zeile aus.



  • @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Ich habe einach eine neue Datei angelegt in der for schleife

    in - warum?



  • @manni66 sagte in Textdatei Komma durch Leerzeichen ersetzen:

    @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Ich habe einach eine neue Datei angelegt in der for schleife

    in - warum?

    Weil dort sehe ich nachher, dass alle zeilen durchgegangen worden sind.

    Ich habe mal das cout außerhalb gelegt, dann bekomme ich exakt eine Zeile ausgegeben.

    Ich glaube es ist irgendwo ein banaler Denkfehler drin.



  • @bthight

    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    
    int main()
    {
    	char const *input_filename  { "whatever.txt" };
    	char const *output_filename { "whatever_replaced.txt" };
    	
    	std::ifstream is{ input_filename };
    	if (!is.is_open()) {
    		std::cerr << "Couldn't open \"" << input_filename << "\" for reading :(\n\n";
    		return EXIT_FAILURE;
    	}
    
    	std::ofstream os{ output_filename };
    	if (!os.is_open()) {
    		std::cerr << "Couldn't open \"" << output_filename << "\" for writing :(\n\n";
    		return EXIT_FAILURE;  // don't have to close is ... RAII
    	}
    
            // copy or replace
    	for (int ch = is.get(); ch != EOF; ch = is.get())
    		os.put(ch == ',' ? ' ' : ch);
    }
    

    fertig.

    Recherchiere was Streams sind. Algorithmen (<algorithm>) machen Dir bloß das Leben leichter.

    In SeppJ's Schreibweise genau das gleiche, brauchst nur cin mit is und cout mit os ersetzen.



  • @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Weil dort sehe ich nachher, dass alle zeilen durchgegangen worden sind.

    Nein. Das ist eine Zeile.

    @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Ich habe mal das cout außerhalb gelegt, dann bekomme ich exakt eine Zeile ausgegeben.

    Wenn myfile.close(); immer noch innerhalb der while-Schleife steht, ist das kein Wunder.



  • @manni66 sagte in Textdatei Komma durch Leerzeichen ersetzen:

    @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Weil dort sehe ich nachher, dass alle zeilen durchgegangen worden sind.

    Nein. Das ist eine Zeile.

    @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Ich habe mal das cout außerhalb gelegt, dann bekomme ich exakt eine Zeile ausgegeben.

    Wenn myfile.close(); immer noch innerhalb der while-Schleife steht, ist das kein Wunder.

    Das war die Lösung. Ich wäre alleine nie drauf gekommen. Und die Output Lösung stimmt nun auch!



  • @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Das war die Lösung.

    Dann kann ich nur hoffen daß Du

    @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Ich werde mir diese Lösung nochmal in mehr Ruhe anschauen müssen, da ich diese Funktionen nie gesehen habe.

    ernst meinst, weil genau das für die meisten Fälle die richtigetm Lösung in C++ ist.



  • @bthight sagte in Textdatei Komma durch Leerzeichen ersetzen:

    Das war die Lösung. Ich wäre alleine nie drauf gekommen

    Beschäftige dich mit dem Debugger. Damit kann man solche Fehler leicht finden.



  • @bthight Davon abgesehen sollte Dir meine Variante davon oben auch einleuchten.



  • @Swordfish sagte in Textdatei Komma durch Leerzeichen ersetzen:

    @bthight Davon abgesehen sollte Dir meine Variante davon oben auch einleuchten.

    // copy or replace
    for (int ch = is.get(); ch != EOF; ch = is.get())
    os.put(ch == ',' ? ' ' : ch);

    Wobei diese Lösung ja wirklich banal ist.

    Ich habe riesen schwierigkeiten mit der Syntax.

    D.h. was darf ich in die Klammern schreiben.

    Aber so sieht es ja sehr plausibel und einfach aus.


Log in to reply