Programm zum Auslesen/Zusammenfassen von Textfiles



  • Steht in einer Referenz deiner Wahl:
    http://www.cplusplus.com/reference/ctime/ctime/



  • Hallo Tehiyok,

    Tehiyok schrieb:

    Könnte mir jemand sagen wo das Format definiert ist? Also irgendwo muss das ja definiert sein das Doppelpunkte verwendet werden, oder sollte ich am Quellcode etwas umschreiben?

    .. BITTE BITTE alle Antworten zu Deinen Fragen noch mal durchlesen!
    Kein Mensch hat hier std::ctime erwähnt!

    Werner Salomon schrieb:

    Hallo,

    .. nur die Ruhe. Deine Frage war:

    Tehiyok schrieb:

    wie kann ich die Zeit automatisch einer Datei als Dateinamen zuweißen?

    Die führende Aussage:

    Tehiyok schrieb:

    das funktioniert aber nicht. Bei dem ersten Code wird mir nur Datum und Zeit angezeigt. Beim zweiten wird die Datei "datum LogFile" genannt.

    war in diesem Kontext etwas irreführend.

    Du kannst das Problem über einen std::ostringstream lösen. Als Anfänger kannst Du das auch nicht wissen. Sieht ungefähr so aus:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <chrono>
    #include <ctime>    // std::time_t
    #include <iomanip>  // put_time
    #include <sstream>  // ostringstream
     
    int main()
    {
        using namespace std;
        auto const maxSenkenGroesse = 10000000;  // Groesse des Output-Files in Byte
     
        int logNr = 1;      // erste Nummer für das File 'TraxisService'
        int quelleNr = 1;   // erste Nummer für die Quelldatei
    
        std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
        std::time_t now_c = std::chrono::system_clock::to_time_t(now - std::chrono::hours(24));
        ostringstream buffer;
        buffer << std::put_time(std::localtime(&now_c), "%Y-%m-%d %H:%M:%S"); // s. http://www.cplusplus.com/reference/ctime/strftime/
        string logName = buffer.str() + " LogFile "; // Datum davor hängen
    
        // usw. wie oben ab Zeile 13
    

    Da ist sogar der Link: http://www.cplusplus.com/reference/ctime/strftime/
    und wenn ein Dateiname keine ':' verträgt - Ok, hat von uns vorher auch keiner dran gedacht - dann ändere halt die Zeile 20 z.B. zu

    buffer << std::put_time(std::localtime(&now_c), "%Y%m%d_%H%M%S"); // Dateiname ohne Sonderzeichen
    

    Und wenn Du eine Antwort nicht verstehst, so frage doch einfach nach.

    Gruß
    Werner



  • Hallo melde mich hier Mal wieder zurück, komme in letzter Zeit einfach viel zu wenig dazu weiterzuarbeiten.

    Zu erst Mal Danke für eure Hilfe.
    Werner schrieb:

    Kein Mensch hat hier std::ctime erwähnt!

    Das ist mir bewusst, ich dachte allerdings das es auch mit ctime funktioniert, weil ich folgendes im Internet gelesen/gefunden habe:

    Interprets the value pointed by timer as a calendar time and converts it to a C-string containing a human-readable version of the corresponding time and date, in terms of local time.

    Ich dachte eigentlich das sich das ganz gut anhört. Heißt das es würde gar nicht mit ctime klappen oder wäre das "umständlicher".
    Mir hat sich jetzt noch eine weitere Frage aufgetan.
    Frage:

    #include <iostream>
    #include <fstream> 
    #include <string> 
    #include <chrono>
    #include <ctime>
    #include <ratio>
    #include <sstream>
    #include <time.h>
    #include <iomanip>
    
    using namespace std;
    using namespace chrono;
    using std::string;
    using std::ostringstream;
    using std::time_put;
    
    int number = 1;
    
    int Stopper;
    
    int main ()
    {
    
    	do
    	{
    		string string1, string2, string3;
    		ostringstream stringnumber;
    
    		stringnumber << number; 
            string1 = "../../LogFiles/TraxisService.log."; 
    	    string3 = string1 + stringnumber.str();
    
    		cout << string3 << endl;
    		number++;
    	} while (number < 5);
            ...
    

    Vorab, das ist eine Testdatei und ich weiß das da zu viele Dinge inkludiert sind die da gerade nicht gebraucht werden.
    Auf jeden Fall geht es um folgendes. Wenn ich diesen Code verwende bekomme ich wenn ich mir string3 couten lasse das richtige raus und zwar:

    ../../LogFiles/TraxisService.log.1 ...

    mit einer vortlaufenden Nummer pro Schleifendurchlauf. Das ist halt das was ich brauche um jeden Schleifendurchlauf die nächste Datei zu öffnen.
    Wenn ich nun aber folgenden Code verwende:

    #include <iostream>
    #include <fstream> 
    #include <string> 
    #include <chrono>
    #include <ctime>
    #include <ratio>
    #include <sstream>
    #include <time.h>
    #include <iomanip>
    
    using namespace std;
    using namespace chrono;
    using std::string;
    using std::ostringstream;
    using std::time_put;
    
    int main ()	
    {
    	int number = 1;
    	auto const maxSenkenGroesse = 10000000;
    	string string1, string2, string3, s;
        ostringstream stringnumber, buffer;
    
        stringnumber << number; 
        string1 = "../../LogFiles/TraxisService.log."; 
    	string3 = string1 + stringnumber.str(); 
    
    	do
    	{
    
    	  cout << string3 << endl;
              ...
    

    funktioniert es nicht. Es erhöht sich die Nummer in string3 nicht mehr und bleibt bei 1 stehen. Wieso funktioniert es wenn ich number als globale Vaiable definiere und alle Deklarationen in die do-Schleife schreibe?



  • Tehiyok schrieb:

    Mir hat sich jetzt noch eine weitere Frage aufgetan.
    Frage:

    ...
    

    Vorab, das ist eine Testdatei und ich weiß das da zu viele Dinge inkludiert sind die da gerade nicht gebraucht werden.
    Auf jeden Fall geht es um folgendes. Wenn ich diesen Code verwende bekomme ich wenn ich mir string3 couten lasse das richtige raus und zwar:

    ../../LogFiles/TraxisService.log.1 ...

    mit einer vortlaufenden Nummer pro Schleifendurchlauf. Das ist halt das was ich brauche um jeden Schleifendurchlauf die nächste Datei zu öffnen.
    Wenn ich nun aber folgenden Code verwende:

    ...
    

    funktioniert es nicht. Es erhöht sich die Nummer in string3 nicht mehr und bleibt bei 1 stehen. Wieso funktioniert es wenn ich number als globale Vaiable definiere und alle Deklarationen in die do-Schleife schreibe?

    das verhalten tritt auf da du "number" - nur in der schleife "hochzählst(number++), was sollte auch passieren wenn du den wert von number dann nur vor deiner schleife dem ostringstream zuweist?

    ...
     stringnumber << number;
     string3 = string1 + stringnumber.str();
    ...
    

    diese zwei zeilen solltest du in der schleife ausführen, nicht davor, da ansonsten number immer den wert 1 hat... (da du ihn nicht neu zuweist)

    du solltest aufjedenfall nochmal recherchieren was du dort machst, es hat für mich nicht den eindruck als hättest du's verstanden.

    ich würde es in etwa so machen:

    ...
    	int number = 1;
    
        string pfad[2];
        ostringstream stringnumber;
    
        for(number=0; number < 3; number++)
        {
        	// leert den ostringstream -- ansonsten 0,01,012 ....
        	stringnumber.str("");
    
        	pfad[number] = "../../LogFiles/TraxisService.log.";
    
        	// +1 ist hier nur da du nicht bei 0 anfängst mit den dateinamen
        	// also : ../../LogFiles/TraxisService.log.1, ../../LogFiles/TraxisService.log.2, etc...
        	stringnumber << number+1;
        	pfad[number] = pfad[number] + stringnumber.str();
            cout << "Pfad:" << pfad[number] << "\n";
    
            cout << "Number: " << number << endl;
        }
    ...
    

    hoff das hat dir geholfen 🙂
    lg



  • diese zwei zeilen solltest du in der schleife ausführen, nicht davor, da ansonsten number immer den wert 1 hat... (da du ihn nicht neu zuweist)

    Also entweder ich habe etwas falsch gemacht oder das stimmt nicht. Ich musste noch

    ostringstream stringnumber;
    

    in die do-Schleife einfügen, dann hat es funktioniert.

    Habe jetzt also folgende drei Zeilen in die do-Schleife eingefügt damit es geht.

    ostringstream stringnumber;
    	  stringnumber << number;
    	  string3 = string1 + stringnumber.str();
    

    Eine Ahnung wieso?
    Lg und Danke Horuzat


  • 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