Text-Dateien (.txt) verändern (HILFE)



  • Hallo,
    ich muss ein Programm schreiben, welches zeichenweise eine Datei (t.txt) liest und in eine zweite Datei schreibt.
    Hierbei sollen alle Kleinbuchstaben im Text als Großbuchstaben in die Ausgabedatei(a.txt) geschrieben werden.(alles andere soll unverändert bleiben)

    Mein Programm sieht bis jetzt so aus:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstring>
    
    using namespace std;
    int main()
    {
    	char zeichen[500];
    
    	ifstream Einlesen;
    
    	Einlesen.open("t.txt", ios::out);
    
    	int k = 0;
    
    	while (!Einlesen.eof()) 
    	{
    		Einlesen >> zeichen[k];
    		k++;
    	}
    
    	Einlesen.close();
    
    	for (int i = 1; i < 499; i++)
    	{	zeichen[i];
    
    		if (zeichen[i] >= 97 && zeichen[i] <= 122)
    		{
    			zeichen[i] - 32;
    		}
    	}
    
    	ofstream Ausgabe; 
    
    	Ausgabe.open("a.txt", ios::out); 
    
    	Ausgabe << zeichen;
    
    	Ausgabe.close(); 
    
    	system("PAUSE");
    	return 0;
    }
    

    folgende Probleme tauchen auf:
    1. Die Leerzeichen werden Nicht mit eingelesen.
    Alle Wörter die vorher durch Leerzeichen getrennt waren sind nun
    hintereinander gereiht.
    (z.B. "Hallo wie geht es Dir?"->"HallowiegehtesDir?")

    2. Die Kleinbuchstaben werden nicht in Großbuchstaben verwandelt.
    Ich habe einen Breakpoint gesetzt und geprüft:
    Das Programm geht zwar in die for-Schleife hinein, jedoch Nicht in meine
    if-Bedingung.
    Ist ein Fehler in meiner if-Bedingung oder kann man hier generell nicht mit
    einer if-Bedingung vorgehen?

    3.Ich habe Problem wie ich ans Ende meines char-Arrays (zeichen[500]) die
    Nullterminierung (\0) setzen kann.
    Ohne Terminierung wird ein Wirrwarr aus Zeichen an meinen Text gehängt.
    Mein Überlegung war, dies so zu gestalten:

    zeichen[500]='\0';
    

    Jedoch funktioniert dann mein Programm garnicht mehr und bricht ab.

    Schonmal vielen Dank für hilfreiche Antworten! 🙂



  • 1. Dazu kann ich nichts sagen, da ich C++ nicht kenne.

    2. Was meinst du was Zeile 31 macht. Schau genau hin.
    Zum testen und umwandeln gibt es schon Funktionen in der cctype: http://www.cplusplus.com/reference/cctype/

    3. Arrays fangen bei 0 an. Das Element mit dem Index 500 (das wäre zeichen[500]) existiert nicht.
    Die Schleife müßte also for (int i = 0; i < 500; i++) sein.

    Aber das ist das falsche Vorgehen.
    Du mußt beide Dateien öffnen, lesen, prüfen, evtl. umwandeln und dann ausgeben.

    Da ist es dann egal wie groß die Datei ist.



  • Ich darf leider keine Bibliotheksfunktionen benutzen 😞


  • Mod

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstring>
    
    using namespace std;
    int main()
    {
    	char zeichen[500];  // Was denn nun, 1 Zeichen oder 500? Deine Bezeichner sollten ausdrücken, was etwas ist.
    
    	ifstream Einlesen;  // Warum nicht gleich hier die Datei öffnen? Ein Verb als Bezeichner für ein Ding ist irgendwie ungünstig
    
    	Einlesen.open("t.txt", ios::out);   // ios::out? Bist du sicher?
    
    	int k = 0;   // Warum liest du erst den ganzen Text anstatt einfach zeichenweise die Datei zu kopieren?
    
    	while (!Einlesen.eof())   // Weitverbreiteter Fehler. Du machst: Prüfen, Lesen, Verarbeiten. Es muss Lesen, Prüfen, Verarbeiten sein. 
                                      // Ein Fehlerstatus wird nach einer misslungenen Leseaktion gesetzt. Soll der Computer etwa in die Zukunft sehen und ihn vorher setzen?
    	{
    		Einlesen >> zeichen[k];  // Wenn du keine Leerzeichen überspringen willst, nutz noskipws oder get.
    		k++;
    	}  // Was, wenn mehr als 500 Zeichen in der Datei stehen?
    
    	Einlesen.close();   // Passiert doch automatisch
    
    	for (int i = 1; i < 499; i++)   // Siehe oben. Warum erst alles einlesen? Was ist mit dem k passiert? Warum gehst du bei 1 los?
    	{	zeichen[i];  // Was macht dies deiner Meinung nach? Tatsächlich macht es gar nichts.
    
    		if (zeichen[i] >= 97 && zeichen[i] <= 122)  // Nutz doch lieber toupper. Das funktioniert auch mit anderen Codierungen.
    		{
    			zeichen[i] - 32;  // Was macht dies deiner Meinung nach? Tatsächlich macht es gar nichts.
    		}
    	}
    
    	ofstream Ausgabe; // Warum nicht gleich hier die Datei öffnen?
    
    	Ausgabe.open("a.txt", ios::out); // ofstream impliziert bereits ios::out
    
    	Ausgabe << zeichen;  // Und wo ist das k geblieben? Was ist, wenn am Ende keine 0 steht? 
    
    	Ausgabe.close(); 
    
    	system("PAUSE");  // Unportabel, unnötig
    	return 0;
    }
    

    Leider ist so ziemlich jede Zeile mindestens ein kleiner Fehler, viele sogar ziemlich dicke Fehler. An sich scheinst du einen Plan zu haben, wie das Programm ablaufen sollte (auch wenn es den wesentlich besseren Plan gäbe, einfach zeichenweise zu kopieren), aber die technische Umsetzung ist mangelhaft.



  • newling987 schrieb:

    Mein Programm sieht bis jetzt so aus:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstring>
    
    using namespace std;  // schlechter Stil
    int main()
    {
    	char zeichen[500];  // was, wenn die Datei groeszer ist?
    
    	ifstream Einlesen;
    
    	Einlesen.open("t.txt", ios::out);  // ifstream mit ios::out? really?
    	                                   // und ueberhaupt, dafuer gibts
    	                                   // einen Konstruktor.
    
    	int k = 0;
    
    	while (!Einlesen.eof()) 
    	{
    		Einlesen >> zeichen[k];  // 1)
    		k++;
    	}
    
    	Einlesen.close();
    
    	for (int i = 1; i < 499; i++)  // 2)
    	{	zeichen[i];  // was macht das?
    
    		if (zeichen[i] >= 97 && zeichen[i] <= 122)  // warum nicht 'a' und 'z' statt der Zahlenwerte?
    		{
    			zeichen[i] - 32;  // 3)
    		}
    	}
    
    	ofstream Ausgabe;
    
    	Ausgabe.open("a.txt", ios::out);  // --> Konstruktor.
    
    	Ausgabe << zeichen;
    
    	Ausgabe.close(); 
    
    	system("PAUSE");  // unportabel, umstaendlich und Sicherheitsproblem
    	return 0;
    }
    

    [...]

    3.Ich habe Problem wie ich ans Ende meines char-Arrays (zeichen[500]) die Nullterminierung (\0) setzen kann. 4)

    1. Der operator>>() überliest standardmäßig Whitespace. Entweder den Manipulator std::noskipws oder std::cin.get() verwenden.
    2. Ein Array T[N] geht in C und in C++ von 0 bis N-1 .
    3. zeichen[i] - 32; ist ein Tolles Statement, nur Speicherst du das Ergebnis nirgends. Das merkt auch dein Compiler. Er weiß, das es keinen Effekt hat und betritt den Schleifenkörper erst garnicht.
    4. Nach deiner (kaputten5) Leseschleife ist k irgendwo in der nähe des zuletzt gelesenen Zeichens im array. zeichen[k] = '\0'; wäre also eine gute Idee.
    5. Du machst: Prüfen auf Fehler, lesen, verarbeiten. Richtig wäre: Lesen, prüfen auf Fehler, verarbeiten.


  • @Swordfish :
    1)Leider hatten wir die Befehle beim Einlesen von Textdateien noch nicht.
    Wenn ich es so schreibe "cin.get(zeichen[k]);" funktioniert das Einlesen nicht
    mehr 😕

    3)ich weiß leider nicht wie ich es speichern sollte. ich hatte folgendes
    probiert, aber so hat es auch nicht funktioniert 😞 :

    char umgewandelt[500];
    for (int i = 0; i < 499; i++)
    	{	
    		if (zeichen[i] >= 97 && zeichen[i] <= 122)
    		{
    			umgewandelt[i] = zeichen[i] - 32;
    
    		}
    		umgewandelt[i] = zeichen[i];
    	}
    
    1. Alles klar vielen Dank! Mit
      zeichen[k-1] = '\0'; funktionierts 🙂


  • so klappt es mit dem Umwandeln von klein in großbuchstaben jetzt 🙂

    for (int i = 0; i < 499; i++)
    	{	umgewandelt[i] = zeichen[i];
    
    		if (zeichen[i] >= 97 && zeichen[i] <= 122)
    		{
    			umgewandelt[i] = zeichen[i] - 32;
    
    		}
    
    	}
    

    Kann mir jemand mit dem Leerzeichenproblem bitte helfen?



  • newling987 schrieb:

    so klappt es mit dem Umwandeln von klein in großbuchstaben jetzt 🙂

    for (int i = 0; i < 499; i++)  // denk nochmal ueber die abbruchbedingung nach
    	{	umgewandelt[i] = zeichen[i];  // erklaer mal wozu?
    
    		if (zeichen[i] >= 97 && zeichen[i] <= 122)  // 'a' und 'z' ...
    		{
    			umgewandelt[i] = zeichen[i] - 32;
    		}
    		
    	}
    

    Das 500-Zeichen Limit besteht immer noch. Wie wäre es, beide Dateien zu öffnen, ein Zeichen zu verarbaiten und gleich in die Ausgabedatei zu schreiben?

    newling987 schrieb:

    Kann mir jemand mit dem Leerzeichenproblem bitte helfen?

    std::cin >> std::noskipws >> zeichen;

    //edit: aja, für die Zukunft: "funktioniert nicht" ist keine Fehlerbeschreibung.


  • Mod

    newling987 schrieb:

    Kann mir jemand mit dem Leerzeichenproblem bitte helfen?

    Ja. Und zwar zwei der Leute, die bereits geantwortet und dir mit diesem Problem geholfen haben. Solche Antworten sind selten dazu gedacht, dass man sie überfliegt und größtenteils ignoriert.



  • @Swordfish

    1. Hab's zu "i<500" verändert!
    2. Damit die zeichen aus "zeichen" in "umgewandelt" gespeichert werden.
      es funktioniert auf alle fälle so bei mir 😕 auch wenn es vllt was umständlich
      ist.. 🙄
      (habe zudem zeile 40 geändert: Ausgabe << umgewandelt;)
    3. Wenn ich "Einlesen" lösche funktionierts nicht mehr.
      Diese beiden Befehle hatten wir zudem noch nicht, daher hab ich auch leider
      Schwierigkeiten damit, wie ich sie anwenden soll.


  • SeppJ schrieb:

    newling987 schrieb:

    Kann mir jemand mit dem Leerzeichenproblem bitte helfen?

    Ja. Und zwar zwei der Leute, die bereits geantwortet und dir mit diesem Problem geholfen haben. Solche Antworten sind selten dazu gedacht, dass man sie überfliegt und größtenteils ignoriert.

    ich hatte die vorgeschlagenen befehle leider noch nicht (wie erwähnt) und hatte gehofft jemand könnte mir genauer etwas dazu erklären und helfen wie genau ich sie anwenden soll! 🙂
    ich programmiere leider noch nicht solange und stehe noch am anfang



  • Du solltest die Antworten auch durchlesen. Durchlesen, nicht überfliegen.

    Hier schreiben Programmierer, die verwenden wenig Prosa. Daher ist das Wissen ziemlich kompakt.

    Das steht schon in der Antwort von Swordfish über dem //edit : https://www.c-plusplus.net/forum/p2437217#2437217



  • dachte das forum sei auch für anfänger gedacht und es wäre nicht schlimm wenn man nochmal nachfragt :S



  • newling987 schrieb:

    dachte das forum sei auch für anfänger gedacht und es wäre nicht schlimm wenn man nochmal nachfragt :S

    Fragen ist nicht schlimm. Wenn Du dann aber die Antworten nicht sorgfältig liest, muß man davon ausgehen, daß Du sie nicht würdigst. Dafür ist aber unser Leben zu kurz, um das widerspruchslos hinzunehmen.


Log in to reply