Programm zum Auslesen/Zusammenfassen von Textfiles


  • Mod

    Ein Stringstream wird nicht leer dadurch, dass du auf seine str-Methode zugreifst. Wenn du, wie Werner Salomon bemerkte, vor der Schleife einmalig den Stringstream mit der Zahl 1 befüllst, dann wirst du bei deinen späteren Zugriffen immer den String "1" erhalten.

    Selbst wenn du in der Schleife weitere Zahlen 2, 3, 4, usw. in den Stringstream schreiben würdest, so würdest du diese bloß hinten an den Inhalt des Stringstreams anfügen und würdest entsprechend "12", "123", "1234", usw. erhalten. Daher muss eines der folgenden Dinge geschehen, damit du die Strings "1", "2", "3", usw. erhältst:
    -Du "leerst" zwischendurch den Stringstream, indem du ihn einen leeren String als Buffer zuweist.
    -Du liest etwas aus. Was hier aber nicht angebracht ist.
    -Du nimmst einfach in jedem Durchlauf einen neuen, frischen Stringstream. Das ist das, was du hier gemacht hast. Ist auch in Ordnung so.



  • Hey Leute.

    Hab hier schon lange nichts mehr geschrieben da ich in letzter Zeit durch verschiedene Faktoren nicht dazu gekommen bin weiterzuschreiben. Seit gestern sitze ich nun wieder daran und habe eigentlich auch das Grundgerüst fertig. Allerdings habe ich nun ein Problem und zwar habe ich irgendwo im Programm einen Logikfehler auf den ich nicht nur nicht drauf komme, sondern der für mich auch keinen Sinn macht. Mir ist bewusst das man hier keine langen Quelltexte posten sollte, aber ich kann den Fehler einfach nicht eingrenzen.

    #include <iostream>
    #include <fstream> 
    #include <string> 
    #include <chrono>
    #include <ctime>
    #include <ratio>
    #include <sstream>
    #include <time.h>
    #include <iomanip>
    #include <stdlib.h>
    #include <conio.h>
    #include <windows.h>
    
    using namespace std;
    using namespace chrono;
    using std::string;
    using std::ostringstream;
    using std::time_put;
    
    int main ()	
    {
    	int number = 1;																							// Start bei 1 da das erste LogFile bei 1 beginnt
    	int DateinummerI = 0;
    	auto const maxSenkenGroesse = 10000000;
    	string string1, string2, string3, logName;
    	ostringstream buffer;
    	unsigned int sleep;
    
        string1 = "../../LogFiles/TraxisService.log.";
    	chrono::system_clock::time_point now = chrono::system_clock::now(); 
        time_t now_c = chrono::system_clock::to_time_t(now - chrono::hours(24)); 
        buffer << put_time(localtime(&now_c), "%Y%m%d_%H%M%S");
    	logName = buffer.str() + ".log ";
    
    	do
    	{
    	  ostringstream stringnumber, buffer;
    	  stringnumber << number;
    	  string3 = string1 + stringnumber.str(); 
    
    	  cout << string3 << endl;                                                           // coutet ../../LogFiles/TraxisService...
    
    	  ifstream LogFile;                                                          
    	  LogFile.open(string3);   
    
    	  if (!LogFile)                                                           
    	  {
    		cerr << "LogFile konnte nicht goeffnet werden.\n";
    	  }
    
    	  else                                                                         
    	  {
    		  if ((number % 5) == 1)												
    		  {
    				string ZusatzS = "_"; cout << "Jetzt" << endl;
    				ostringstream DateinummerOS;
    
    				DateinummerI++;
    				DateinummerOS << DateinummerI;
    
    				ZusatzS += DateinummerOS.str();
    				logName += ZusatzS;
    
    			    ofstream Zieldatei (logName);                                      
    				if (!Zieldatei)                                               
    				{
    				  cerr << "Ausgabe-Datei kann nicht geöffnet werden\n"; 
    				}
    				else 
    				{                                                                  
    					char c;                                                      
    					while (LogFile.get(c))                                   
    					{
    						Zieldatei.put(c);                                 
    					}
    				}
    
    				Zieldatei << "\n" << endl;
    		  }
    		  else
    		  {
    			   ofstream Zieldatei (logName, ios::app);
    			   if (!Zieldatei)                                               
    			   {
    				  cerr << "Ausgabe-Datei kann nicht geöffnet werden\n"; 
    			   }
    			   else 
    			   {                                                                  
    					char c;                                                      
    					while (LogFile.get(c))                                   
    					{
    						Zieldatei.put(c);                                 
    					}	
    			   }
    					Zieldatei << "\n" << endl;
    		  }
    	  }
    
    	  number++;
    
    	} while  (number < 8);
    
      while (1) 
      getchar(); 
    
     return 0;
    }
    

    Folgender Fehler. Die ersten 4 Male klappt alles wie es sollte. Wenn es dann zum 5. kommt kriege ich beim "cout << string3" das richtige raus, sprich string3 stimmt. Trotzdem gibt er mir dann die Fehlermeldung "LogFile konnte nicht geoffnet werden aus". Danach macht er normal weiter. Im Endeffekt heißt das, dass ich in den 2 generierten files dann den Inhalt von LogFile 1,2,3,4 habe (wo auch der von 5 stehen sollte) und im zweiten dann 6,7. Und das verstehe ich nicht. Ich könnte es ja noch irgendwie verstehen das es beim 6. ein Problem gäbe, weil da ja ein neues file generiert wird, aber das ist eben nicht der Fall. Ich hoffe es hat jemand Zeit und Lust mir zu helfen ^^



  • Hallo Tehiyok,

    der von Dir beschrieben Fehler liegt nicht in Deinem Programm. Vielleicht ist die Datei TraxisService.log.5 von einer anderen Applikation (Editor?) geöffnet oder Du hast sie aus Versehen gelöscht.

    Wenn Du anschließend mit folgender Variante Deines Programms weiter arbeitest, tust Du uns allen einen Gefallen 😉 :

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <chrono>
    #include <sstream>
    #include <iomanip>
    
    int main ()
    {
        using namespace std;
        const string logFilePrefix = "../../LogFiles/TraxisService.log.";
        chrono::system_clock::time_point now = chrono::system_clock::now();
        time_t now_c = chrono::system_clock::to_time_t(now - chrono::hours(24));
        ostringstream buffer;
        buffer << put_time(localtime(&now_c), "%Y%m%d_%H%M%S");
        string zielNameBase = buffer.str() + ".log ";
    
        int logFileNumber = 1;  // Start bei 1 da das erste LogFile bei 1 beginnt
        for( int ZielnummerI = 0; logFileNumber < 8; ++ZielnummerI ) // .. über die Zieldateien
        {
            string zielName = zielNameBase + "_" + to_string( ZielnummerI );
            cout << "Oeffne Zieldatei: " << zielName << endl;
            ofstream Zieldatei (zielName);                                      
            if (!Zieldatei.is_open())                                              
            {
                cerr << "Ausgabe-Datei kann nicht geöffnet werden\n";
                break;
            }
    
            for( int i=0; i<5; ++i, ++logFileNumber )  // über eine Untermenge der Log-Dateien
            {
                string logFilePath = logFilePrefix + to_string( logFileNumber ); 
                cout << "Oeffne Logfile " << logFilePath << endl;       // coutet ../../LogFiles/TraxisService...
                ifstream LogFile(logFilePath);                                                           
                if (!LogFile.is_open())                                                          
                {
                    cerr << "LogFile konnte nicht goeffnet werden.\n";
                    continue;   // -> nächstes Logfile
                }
                Zieldatei << LogFile.rdbuf() << "\n" << endl;
            }
        }
        return 0;
    }
    

    Gruß
    Werner



  • ... der von Dir beschrieben Fehler liegt nicht in Deinem Programm.

    Vielen Dank für den Tipp!!! Ich habe daran eigentlich auch gedacht, es aber für unwahrscheinlich abgestempelt. Im Endeffekt ist das Problem gewesen das ich bei besagter Datei5 nicht ".log.5" sondern ".log. 5" stehen hatte, was mir durch den Zeilenumbruch von Windows nicht aufgefallen ist...
    Mir ist bewusst das mein Code umständlich und laienhaft ist, allerdings bin ich gerade froh es wenigstens funktionsfähig hinzukriegen ohne auf die Form zu schauen. 🙂
    Lg Tehiyok

    Edit: Ich hab mir deinen Code kurz angeschaut und mir ist aufgefallen das da was fehlt.

    if ((number % 5) == 1)
    

    Das steht bei dir nicht, oder habe ich was übersehen? Und das brauche ich ja um nach jedem 5. LogFile eine neue Datei zu erstellen.



  • Hallo Tehiyok,

    Tehiyok schrieb:

    Ich hab mir deinen Code kurz angeschaut und mir ist aufgefallen das da was fehlt.

    if ((number % 5) == 1)
    

    Das steht bei dir nicht, oder habe ich was übersehen?

    Ja - ich habe die Struktur des Programms so verändert, dass das gar nicht mehr nötig ist. Schaue Dir die beiden geschachtelten for-Schleifen an.



  • Hmmm stimmt. Ich bevorzuge es allerdings meinen Code zu verwenden, einfach weil ich den einigermaßen verstehe und ja 😃
    Ich stehe hier gerade wieder vor einem Problem. Ich habe nach einer Möglichkeit gesucht die Anzahl an Daten in einem Ordner zu zählen und anschließend in einer Variable zu speichern (damit die Schleife weiß wie oft sie laufen muss). Gestoßen bin ich da auf "WIN32_FIND_DATA" und "FindFirstFile". Ist das die beste Möglichkeit, bzw. einzige? Und kennt da jemand einen guten ref link wo es gut erklärt wird? Habe in denen die ich bisher gefunden habe nicht wirklich viel verstanden.
    Lg und Danke Tehiyok



  • Tehiyok schrieb:

    Ich habe nach einer Möglichkeit gesucht die Anzahl an Daten in einem Ordner zu zählen und anschließend in einer Variable zu speichern (damit die Schleife weiß wie oft sie laufen muss).

    Ich verstehe nicht, was du mit dem "damit die Schleife weiß wie oft sie laufen muss" sagen willst. Entweder du willst nur die Anzahl haben - oder du willst über die Dateien iterieren (dann brauchst du aber vorher nicht zu wissen, wie viele Dateien es sind).

    Tehiyok schrieb:

    Gestoßen bin ich da auf "WIN32_FIND_DATA" und "FindFirstFile". Ist das die beste Möglichkeit, bzw. einzige? Und kennt da jemand einen guten ref link wo es gut erklärt wird?

    Wird hier erklärt:
    https://msdn.microsoft.com/en-us/library/windows/desktop/aa364418(v=vs.85).aspx

    Alternative ist zum Beispiel: http://www.boost.org/doc/libs/1_61_0/libs/filesystem/doc/tutorial.html#Directory-iteration



  • Ich verstehe nicht, was du mit dem "damit die Schleife weiß wie oft sie laufen muss" sagen willst.

    Nun ja, ich habe in meinem Code eine Schleife die pro Durchlauf eine Datei ließt, speichert. Nächste Datei ließt, speichert usw.
    Damit ich nicht pauschal schreibe das die Schlaufe zum Beispiel 100 Mal läuft, möchte ich die Anzahl der Datein in dem jeweiligen Ordner in eine Variable speichern, wodurch die Schleife dann genau weiß wie oft sie laufen muss.



  • Tehiyok schrieb:

    Ich habe nach einer Möglichkeit gesucht die Anzahl an Daten in einem Ordner zu zählen

    Das passiert in einer Schleife.
    Die Abbruchbedingung ist: "keine Dateien mehr vorhanden"

    Du weißt vorher nicht wie oft die Schleife durchlaufen wird.

    Tehiyok schrieb:

    Damit ich nicht pauschal schreibe das die Schlaufe zum Beispiel 100 Mal läuft, möchte ich die Anzahl der Datein in dem jeweiligen Ordner in eine Variable speichern, wodurch die Schleife dann genau weiß wie oft sie laufen muss.

    Das ist doch gar nicht nötig. Beim Dateizählen klappt das doch auch.

    Warum machst du das nicht alles in der ersten Schleife.



  • Warum machst du das nicht alles in der ersten Schleife.

    Ich bin mehr oder weniger kompletter Beginner und wusste nicht ein Mal das das geht. Danke für deinen Rat ^^



  • Ich melde mich hier Mal wieder zurück 🙂
    Hatte in den letzten Tagen leider nicht ganz so viel Zeit, hab mir aber den Vorschlag zu EOF ein wenig angeschaut. Habs auch gleich probiert bin aber auf ein Problem gestoßen. Ich habe jetzt halt das

    do {} while ()
    

    mit einer normalen

    while ()
    

    Funktion ersetzt, in welche ich dann das EOF schreibe. Und jetzt gibt es folgendes Problem (ich verweiße da auf den Quellcode den ich in einem letztern Post geschrieben habe), das EOF bezieht sich da auf LogFile/string3. Das habe ich hier deklariert:

    ostringstream stringnumber, buffer;
    	  stringnumber << number;
    	  string3 = string1 + stringnumber.str(); 
    
    	  cout << string3 << endl;
    
    	  ifstream LogFile;                                                          
    	  LogFile.open(string3);
    

    Das Problem dabei ist das ich ganz am Ende der Schleife, die Variable number immer um eins erhöhe damit halt die Dateien "hochgezählt" werden. Das bedeutet das ich die Deklaration die ich oben gechrieben habe, in der Schleife habe damit ich es eben hochzählen kann, gleichzeitig brauche ich aber auch LogFile/string3 vor der ersten while Schleife um es eben als Abbruchbedingung zu verwenden. Vor der Schleife kann ich es auch nicht machen, da sich LogFile/string3 dann nicht erhöht. Gibt es da irgendeine Möglichkeit die ich übersehe/nicht weiß? Danke und Lg 😃


Anmelden zum Antworten