[GELOEST]komme nicht weiter datei neu-einlesen loop erzeugen



  • Hallo gemeinde,

    Ich bin neu hier deswegen erst einmal hallo 🙂
    Meine Kenntnisse der Programmierung sind leider sehr eingeschraenkt. Falls ich Hilfe bekommen sollte, waere es nett dies mit einzubeziehen.

    Gegeben:
    Ein Program schreibt unregelmaessig ein output in einem file...

    Zur selbstgestellten aufgabe :
    1.Lies das file ein.
    2.Suche nach koordinaten von Punkt.
    3.Loesche den Inhalt des Files.
    4.Visualisiere sie. //das ist eine andere baustelle
    5.Geh zur step 1

    mein bisheriger code

    #include <iostream>
    #include <algorithm>
    
    #include <SDL2/SDL.h>
    #include <SDL2/SDL_image.h>
    #include <stdio.h>
    #include <string>
    
    #include <streambuf>
    #include <fstream>
    #include <vector>
    #include <sstream>  // String-Ein-/Ausgabe
    
    using namespace std;
    
    int main(int argc, char *argv[])
    { 
    
      string line;
    
      size_t suchepoint;
      size_t pos;
    
      double zahlx;
      double zahly;
    
      istringstream strin2;
      istringstream strin;
    
      int lline;
      int position;
    
      fstream myfile ("cout.txt", ios::out | ios::in );
    
    	while (myfile.is_open())
    	{
    
    	getline (myfile,line);   // Lese eine Zeile
    
    		while(!line.empty())		
    		{
    
    		int zahlten = line.length(); 
    
    		//ist die laenge von zahlten(10 =3) ungleich 3
    		if(zahlten != 3)
    		{
    			while ( !myfile.eof() )
    			{
    			getline (myfile,line);   // Lese eine Zeile
    
    			suchepoint = line.find("point");
    			pos = line.find("pos(");
    
      			if(suchepoint==string::npos)
       			continue;
    
    			//anfang bis koordinatenbeginn
    			line.erase(line.begin(),line.begin()+pos+4);
    
    			//17 weil 2x7stelligezahl+2vorzeichen+1 leerzeichen
    			line.erase(line.begin()+17,line.end());
    
    			//laenge des strings bestimmen = 17 da wie oben 2*7+2+1
    			//lline = line.length();
    
    				//falls die koordinate das unsichtbare + zeichen hat loesche es
    				if(position = line.find(" ") == 0 ){
    				// loeche erstes leezeichen
    				line.erase(0,1);
    				}
    
    			//liefert die posi wo der sting gerade ist leerzeichen
    			position = line.find(" "); 
    
    			// sting in double umwandeln 
    			strin.str(line);           // Streaminhalt mit String-Variable füllen
    
     			strin >> zahlx;             // ganzzahlige Variable von Eingabe-Stream einlesen
    
    			std::cout << zahlx << std::endl; // Zahlx ausgeben
    			//return zahlx;
    
    			//loecht bis zum y wertleerzeichen und das leerzeichen+1
    			line.erase(line.begin(),line.begin()+position+1); 
    
    			strin2.str(line);           // Streaminhalt mit String-Variable füllen
    
     			strin2 >> zahly;             // ganzzahlige Variable von Eingabe-Stream einlesen
    
    			std::cout << zahly << std::endl; // Zahly ausgeben
    			//return zahly;
    
    			}
    /*
    		//datei cout leeren indem der inhalt durch eine 10 + das leerzeichen ersetzt wird 
    		myfile.close();
    		ofstream myfile;
    		myfile.open ("cout.txt");
    			if (myfile)
     		 	{
    			int var1 = 10;
    
    			myfile << var1 << ' ';
    			myfile.close();
    			ifstream myfile ("cout.txt");
    			//line = 10;				
    			}
    */
    
    		}//if(zahlten != 3)
    
    		else
    		//noch in der while(!line.empty()) schleife
    
    		// Falls zahlten(int var1 = 10; + leerzeichen) 3 ist soll die Datei immer wieder neu eingelesen werden
    		// bis zahlten nichtmehr 3 ist. Dann soll die obere if abfrage greifen.
    		{
    
    		cout << "else" << endl;	
    		}
    
    		}//while(!line.empty())
    
    	}//while (myfile.is_open())
    
    /*
    //if(myfile.is_open())
    	else 
    	{  
     	cout << "Unable to open file"; 
    	}
    */
    
    cout << "ganz am ende" << endl;
    }
    

    cout.txt

    ent(  9) pos( 803.37  2569.41  134.60) circle
    ent( 312) pos( 1088.00  432.00  152.00) point
    ent(  9) pos( 803.37  2569.41  134.60) circle
    ent( 160) pos( 1328.00  440.00  208.00) point
    ent(  2) pos( 795.55  1937.19  130.09) circle
    ent( 139) pos( 1200.03  480.34  113.72) quader
    ent(  5) pos( 632.08  2076.48  197.85) point
    ent(  0) pos( 816.40  1864.03  179.75) point
    ent(  0) pos( 816.40  1864.03  179.75) quader
    ent( 139) pos( 1200.03  480.34  113.72) point
    ent(  0) pos( 816.40  1864.03  179.75) quader
    ent( 160) pos( 1328.00  440.00  208.00) point
    

    Ausgabe erst x koordinate darunter y

    major@major:~/g++$ g++ zhard.cpp -w -lSDL2 -lSDL2_image -o zhard
    major@major:~/g++$ ./sworkinc 
    major@major:~/g++$ ./sworkinc 
    major@major:~/g++$ ./zhard 
    1088
    432
    1328
    440
    632.08
    2076.48
    816.4
    1864.03
    1200.03
    480.34
    1328
    440
    ^C
    major@major:~/g++$
    

    Dafuer hab ich 2 wochen gebraucht 🙂 nun haenge ich aber beim unteren else.
    Ich hatte es mit freopen versucht, oder sprungmarken wie marke:anweisung marke
    aber ich komme da irgentwie nichtmehr alleine weiter. Es waere nett, wenn mir der richtige denkschubser gegeben wird 👍

    mfg

    ps zu test zwecken hatte ich das loeschen auskommentiert.



  • Hallo Justin,

    Willkommen im C++-Forum.

    Zunächst möchte ich Dir eine gänzlich andere Vorgehensweise beim Einlesen der Datei vorschlagen. Lese zunächst den Inhalt einer Zeile in einer Form ein, mit der Du auch was anfangen kannst - also zwei Zahlen und ein Wort - prüfe dann das Wort auf 'point' und danach kannst Du die Zahlen ausgeben bzw. abspeichern.
    Das ist alles einfacher und übersichtlicher als das was Du da machst.

    Ich unterstelle, dass die Datei 'cout.txt' parallel zu Deinem Programm von einem zweiten Programm geschrieben wird. Die Vorgehensweise, die Du gewählt hast wird wahrscheinlich gar nicht oder nicht sicher funktionieren. Das ganze hängt von der Schnittstelle zu Deinem Betriebssystem ab. Wenn Du eine Datei zum Lesen UND Schreiben öffnest, blockierst Du die Datei für andere. D.h. niemand kann dann etwas hinzufügen. Also musst Du sie zwischenzeitlich wieder 'loslassen' - also schließen.
    Unterm Strich würde ich vorschlagen, dass Du einen Pipe-Mechanismus wählst. So weit ich weiß, kannst Du unter Linux die Ausgabe eines Programms als Eingabe in ein anderes Programm umlenken. Ist dies der Fall musst Du intern nur von std::cin (statt von myfile) lesen.
    Möge dir ein Linux-User das detaillierter erklären.

    Anbei mein Entwurf Deines Programms - noch mit 'fstream myfile', was ich wie oben erläutert nicht für die endgültige Lösung halte:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <tuple>
    #include <limits>  // numeric_limits<>
    #include <vector>
    
    int main()
    {
        using namespace std;
    
        vector< tuple< double, double > > allePunktKoordinaten; // hier sollen die Koordinaten reinkommen
        for(;;) // forever !?
        {
            fstream myfile("cout.txt");
            if( !myfile.is_open() )       // beim Lesen immer prüfen, ob die Datei auch vorhanden bzw. offen ist.
            {
                cerr << "Fehler beim Oeffnen der Datei" << endl;
                return 0;   // exit oder continue??
            }
            auto const ALLES = numeric_limits< streamsize >::max();
            for(;;)
            {
                myfile.ignore( ALLES, ')' );    // bis "ent( zahl )
                myfile.ignore( ALLES, '(' );    // bis "ent( zahl ) pos(
                double zahlx, zahly;
                myfile >> zahlx >> zahly;       // liest bis "ent( zahl ) pos( x y
                myfile.ignore( ALLES, ')' );    // ...   bis "ent( zahl ) pos( x y zahl )
                string typ;
                myfile >> typ;
                if( myfile.fail() )
                    break;  // Lesen zu Ende
                if( typ != "point" )
                    continue;   // zur nächste Zeile
    
                cout << zahlx << "\n" << zahly << endl; // auf Standard-Ausgabe ausgeben
                allePunktKoordinaten.push_back( make_tuple( zahlx, zahly ) );   // Koordinate merken
            }
            cout <<  allePunktKoordinaten.size() << " Koordinaten mit point gelesen" << endl;
            if( myfile.eof() )
                cout << "alles Ok; Datei bis zum Ende gelesen" << endl;
    
            // --   Datei löschen
            // mit System-Aufruf
    
            // hier ggf. eine Wartezeit einfügen!
        }
        return 0;
    }
    

    Gruß
    Werner



  • Hallo werner

    Ich danke dir fuer die erklaerungen und den zur aufgabenstellung perfekt funktionierenden code. 👍

    Leider war ich schon soweit in "meinen" code, dass ich die cout.txt auch nur nach diesen kriterien dargestellt habe. Vor dem ent, sowie nach den koodinaten und nach dem ziel string koennen wahllos random strings und zahlen stehen.

    Dank deiner hilfe konnte ich die selbstgestellte aufgabe dennoch loesen.

    Mit viel es nicht einfach dein code zu interpretieren und die startpage suche gab gerade mal 3 seiten zu .ignore aus. Ich haette es gerne auch auf deinen weg versucht. Ev kannst du ja ein kommentar abgeben ob die dein code so richtig verstanden habe.

    hier meine loesung aufgwertet durch deinen code

    cplusnet.cpp

    #include <iostream>
    
    #include <string>
    #include <tuple>
    #include <limits>  // numeric_limits<>
    #include <vector>
    
    #include <stdlib.h> 
    #include <time.h>
    #include <unistd.h>
    
    #include <streambuf> 
    #include <sstream>  // String-Ein-/Ausgabe
    #include <SDL2/SDL.h>
    #include <SDL2/SDL_image.h>
    #include <fstream>
    
    using namespace std;
    
    int main()
    {
    
       size_t suchepoint;
       size_t pos;
    
       int position;
       istringstream strin; 
       istringstream strin2;
    
       string line;
    
       double zahlx;
       double zahly;
    
        //1te enlossschleife liest datei immer wieder neu ein
        for(;;) // forever !?
        {
    
            fstream myfile("cout.txt"); //erzeugt den datei-einleseloop
            if( !myfile.is_open() )       // beim Lesen immer prüfen, ob die Datei auch vorhanden bzw. offen ist.
            {
                cerr << "Fehler beim Oeffnen der Datei" << endl;
                return 0;   // exit oder continue??
            }
    
    	//2te "fuer immer" schleife
            for(;;)
            {
    
    	getline (myfile,line);   // Lese eine Zeile
    
    	//gehoert wohl zur endloschleife
    	if( myfile.fail() )
    	break;
    
    	//wenn "point" in der zeile ist
            suchepoint = line.find("point");
            pos = line.find("pos(");
    
            if(suchepoint==string::npos)
            continue;
    
            //anfang bis koordinatenbeginn
            line.erase(line.begin(),line.begin()+pos+4);
    
            //17 weil 2x7stelligezahl+2vorzeichen+1 leerzeichen
            line.erase(line.begin()+17,line.end());
    
    	if(position = line.find(" ") == 0 )
    		{
    
            	// loeche erstes leezeichen
            	line.erase(0,1);
             	}
    
           //liefert die posi wo der sting gerade ist leerzeichen
           position = line.find(" ");
    
           // sting in double umwandeln
           strin.str(line);           // Streaminhalt mit String-Variable füllen
    
           strin >> zahlx;             // ganzzahlige Variable von Eingabe-Stream einlesen
    
           std::cout << zahlx << std::endl; // Zahlx ausgeben
    	//return zahlx;
    
           //loecht bis zum y wertleerzeichen und das leerzeichen+1
           line.erase(line.begin(),line.begin()+position+1);
    
           strin2.str(line);           // Streaminhalt mit String-Variable füllen
    
           strin2 >> zahly;             // ganzzahlige Variable von Eingabe-Stream einlesen
    
           std::cout << zahly << std::endl; // Zahly ausgeben
    	//return zahlx;
    
            }// 2te for(;;) schleife
    
        		if( myfile.eof() )
    
        			cout << "alles Ok; Datei bis zum Ende gelesen" << endl;
    
        			//datei schliessen 
        			myfile.close(); 
    
        			//datei neu oeffnen mit schreibrechten
        			ofstream myfile1; 
        			myfile1.open ("cout.txt"); 
    
        			//beliebiger wert zum ueberschreiben der datei
        			int var1 = 10;
    
        			//file wird ueberschrieben und geschlossen(freigegeben)           
        			myfile << var1 << ' ';
        			myfile1.close(); 
    
        			//wartezeit
        			sleep(1); //zu langsam aber gut zum testen
        			//usleep(100000);//0.1sekunden geht ab
    
        }//1te (for(;;) // forever !?) schleife
    
        return 0;
    
    }//main funktion zu
    

    cout.txt

    Lorem ipsum dolor sit amet, t *(*())*(uyam ent(  9).37  2569.41  134.60)Lorem consetetur sadipscing e(*((())litre magna aliquyam  circle
    ent( 312) pos( 1088.00  432.00  152.00) Lorem ipsum dolor sit amet, consetetur sadit ut labore et dolore magna aliquyam
    abore et dolore magna  ent(  9) pos( 803.37  2569.41  134.60) Lorem point ipsum dolor sit amet, con circle Lorem ipsum dolor sit amet, con
    Lorem ipsum dolor sit amet, consetetur sadipscing elitr,e magna aliquyam ent( 160) pos( 1328.00  440.00  208.00) abore et (42 )dolore magna  point abore et dolore magna 
    ent(  2) pos( 795.55  1937.19  130.09) circle
    test
    ()()
    Lorem ipsum dolor sit amet, con(5)(6)(7)(8)(9)(9)
    Lorem ipsum ()() ent( 139) pos( 1200.03  480.34  113.72) Lorem ipsum dolor sit amet, con quader Lorem ipsum dolor sit amet, con
    Lorem ipsum dolor sit amet, con ent(  5) pos( 632.08  2076.48  197.85) Lorem ipsum dolor sit amet, con ()(78) point
    

    ausgabe

    major@major:~/g++$ g++ cplusnet.cpp -w --std=gnu++11 -lSDL2 -lSDL2_image -o ccplusnet
    major@major:~/g++$ ./ccplusnet 
    803.37
    2569.41
    1328
    440
    632.08
    2076.48
    alles Ok; Datei bis zum Ende gelesen
    alles Ok; Datei bis zum Ende gelesen
    alles Ok; Datei bis zum Ende gelesen
    ^C
    major@major:~/g++$
    

    wenn man nun daten in die txt kopiert und speichert werden diese ausgelesen, angezeigt und geloescht

    nochmal vielen dank fuer die hilfe

    habe ich dein code richtig verstanden ?

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <tuple>
    #include <limits>  // numeric_limits<>
    #include <vector>
    
    int main()
    {
        using namespace std;
    
    	//sowas wie ein array speichert 2 werte in tulpe[0]
        vector< tuple< double, double > > allePunktKoordinaten; // hier sollen die Koordinaten reinkommen
    
    	//erzeugt den dateieinleseloop
        for(;;) // forever !?
    
        {
            fstream myfile("cout.txt");
    
            if( !myfile.is_open() )       // beim Lesen immer prüfen, ob die Datei auch vorhanden bzw. offen ist.
            {
                cerr << "Fehler beim Oeffnen der Datei" << endl;
                return 0;   // exit oder continue??
            }
    
    	//definiert ALLES als jedmoeglichen string oder zahl art
            auto const ALLES = numeric_limits< streamsize >::max();
    
            for(;;)
            {
    
                myfile.ignore( ALLES, ')' );    // bis "ent( zahl )
                myfile.ignore( ALLES, '(' );    // bis "ent( zahl ) pos(
                double zahlx, zahly;
                myfile >> zahlx >> zahly;       // liest bis "ent( zahl ) pos( x y
                myfile.ignore( ALLES, ')' );    // ...   bis "ent( zahl ) pos( x y zahl )
                string typ;
                myfile >> typ;
    
    		//warum sorgt das dafuer, dass die schleife nie endet?
                if( myfile.fail() )
                    break;  // Lesen zu Ende
    
    		//falls point ungleich typ ist geht zu naechsten zeile
                if( typ != "point" )
                    continue;   // zur nächste Zeile
    
    		//ausgabe
                cout << zahlx << "\n" << zahly << endl; // auf Standard-Ausgabe ausgeben
                allePunktKoordinaten.push_back( make_tuple( zahlx, zahly ) );   // Koordinate merken
            }
    		//gib die anzahl der gespeicherten koordinaten aus
            cout <<  allePunktKoordinaten.size() << " Koordinaten mit point gelesen" << endl;
            if( myfile.eof() )
                cout << "alles Ok; Datei bis zum Ende gelesen" << endl;
    
            // --   Datei löschen
            // mit System-Aufruf
    
            // hier ggf. eine Wartezeit einfügen!
        }
        return 0;
    }
    

    mfg


Anmelden zum Antworten