Logfile



  • Ich würde eher die globale getline()-Funktion verwenden:

    std::string Zeile;
    ...
    std::getline(infile,Zeile);
    

    Der nächste Schritt wäre es dann, die Zeilen zu zerlegen:

    int tag,monat,jahr,stunde,minute,sekunde;
    std::string nachricht;
    std::istringstream Parser(Zeile);
    Parser >> tag >> monat >> jahr;
    Parser >> stunde >> minute >> sekunde;
    std::getline(Parser,nachricht);
    _records.push_front(record(tag,monat,jahr,stunde,minute,sekunde,nachricht));
    

    SonjaZ schrieb:

    Ich bin wirklich etwas unsicher, ob mein Code stimmt. Denn das file sollte (so die Aufgabenstellung, neben der bereits erwähnten) geöffnet bleiben, bis das logfile Objekt zerstört wird.

    Auch wenn ich nicht weiß wozu es gut ist - dazu muß dein Stream solange geöffnet halten, wie du es brauchst. Das heißt du solltest den Stream als Member der Log-Klasse unterbringen (dann wird er erst im Destruktor wieder freigegeben).



  • Dankeschön!

    Gut, also meinst du, dass ich im Headerfile das speichern sollte:

    protected:	
    std::fstream _file;
    

    ? ..und wie im Source-Code verwenden?

    ..oder hast du es nicht so gemeint?



  • Ja, so hatte ich das gemeint - und verwenden solltest du es anstelle des lokal definierten ifstream, den du dort oben verwendet hast (für solche Situationen hast du dann die Methode open() ).



  • Ahh..raffiniert 😃
    ..noch 2 Fragen hätte ich:

    1.) Kann es an meinem Programm liegen (Visual), oder hab ich was vergessen zu implementieren? Bei deinen Zeilen will es meinen Parser nicht annehmen, zudem jammert der Compiler wegen den "<<" und dem "getline".

    2.) Bei einem Destruktor - reicht dort einfach

    _file.close();
    

    oder muss man dort noch mehr berücksichtigen?



    1. hast du die Stream-Header (fstream und stringstream) eingebunden?

    2. der Destruktor von fstream schließt die verarbeitete Datei automatisch - und der Destruktor deiner Klasse wird auch die Destruktoren der Member aufrufen. Das bedeutet, du mußt dich dort um gar nichts kümmern - der Compiler wird das für die erledigen.
      (das sind die Vorteile von RAII)



    1. #include <iostream> ?
    2. Das müsste reichen.


  • Ok. Also nur um sicher zu gehen: Ich muss gar nichts implementieren, oder lediglich "delete logfile"?

    Ja, ich habe alles eingebunden. Bei " Parser >> tag >> monat >> jahr; " unterliniert Visual einfach das erste ">>" und auch getline wird unterliniert.



  • SonjaZ schrieb:

    Ok. Also nur um sicher zu gehen: Ich muss gar nichts implementieren, oder lediglich "delete logfile"?

    das kommt darauf an, ob du dein Logfile auf dem Stack oder auf dem Heap angelegt hast - wenn du es per new erzeugst, mußt du es auch per delete freigeben. Lokale Variablen werden automatisch entsorgt, wenn sie nicht mehr benötigt werden.

    Ja, ich habe alles eingebunden. Bei " Parser >> tag >> monat >> jahr; " unterliniert Visual einfach das erste ">>" und auch getline wird unterliniert.

    Sorry, das sollte natürlich ein istringstream sein. Und das getline liegt immer noch im Namensraum std.



  • Komisch, <istringstream> wird bei mir nicht gefunden :S
    ..also doch ein Visual-"Problem"?



  • Nein, der Header heißt schon <stringstream>, die Klasse zum Parsen der Logzeile wäre istringstream (i wie input - d.h. sie liest den übergebenen String und veteilt ihn in die Variablen).
    Ich hab' den Code da oben mal überarbeitet, der sollte jetzt so passen.

    PS: Es ist vielleicht eine gute Gelegenheit, dir einen tieferen Blick in die Stream-Bibliothek zu empfehlen 😉



  • Yeah super! 😃
    Eine kleine Änderung, und alles funktioniert 🙂

    Vielen Dank für Deine Hilfe und die Tipps!



  • SonjaZ schrieb:

    Yeah super! 😃
    Eine kleine Änderung, und alles funktioniert 🙂

    Hast du auch verstanden warum? 😉 (Wenn nicht, dann versuche es wenigstens, dann hättest du was gelernt, was wiederum ein Erfolgserlebnis für diejenigen wäre, die dir geholfen haben)



  • Doch, natürlich 🙂
    O --> Output
    I --> Input
    Das wusste ich wirklich nicht, wofür das o und das i jeweils vor den Bibliotheken steht - aber nun ist es ganz klar!

    Ich hätte doch noch eine Programmier-spezifische Frage: Warum kann ich meine print-Funktion nicht so machen?

    for(int i = _records.size(); i <= 0; --i)
    	{
    		std::cout << _records.front() << std::endl;
    		_records.pop_front();
    	}
    

    Der Compiler unterstreicht die "<<" bei cout.



  • Um deine Log-Einträge auszugeben, mußt du der Klasse noch einen Ausgabe-Operator spendieren, der etwa so aussehen könnte:

    ostream& operator<<(ostream& out, const record& daten)
    {
      // den Teil bekommst du alleine hin ;)
      return out;
    }
    

    PS: Ich hab' diese Sofort-Analyse zwar bisher nur mit C# erlebt, aber der MSVS liefert auch eine Liste mit den Fehlertexten, die es angestrichen hat.



  • Ich kann doch nun einfach

    out << daten.get_day(); 
    // usw.
    

    machen, oder irre ich mich da?
    [offenbar schon, denn meinem Compiler gefällt das nicht allzu sehr]



  • wenn du noch die ganzen get-Methoden der Klasse als const definierst, sollte es eigentlich funktionieren.
    (und das nächste Mal liest du auch die Erklärungen des Compilers, was an deinem Code nicht in Ordnung ist)



  • Vielen Dank für deine Geduld!
    Das mach ich jeweils schon, aber ich verstehe die Meldung nicht immer.

    Ich hätte noch eine Frage, aus reiner Neugier:
    Wie sähe es in umgekehrter Richtung aus? Also dass man eine Fehlermeldung in ein File speichert?
    Ich meine, klar, man könnte so beginnen:

    void
    logfile::log(std::string message_)
    

    und schon hat man die Mitteilung.
    Für die Zeit gibt es doch Methoden aus der Bibliothek, oder?
    Aber wie sähe eine mögliche Speicherung in einem file aus?

    Liebe Grüsse und eine gute Nacht,
    Sonja



  • SonjaZ schrieb:

    Vielen Dank für deine Geduld!
    Das mach ich jeweils schon, aber ich verstehe die Meldung nicht immer.

    Dann solltest du wenigstens dazuschreiben, was der Compiler gesagt hat (Aussagen wie "meinem Compiler gefällt das nicht allzu sehr" sind zu allgemein für eine genauere Analyse)

    Ich hätte noch eine Frage, aus reiner Neugier:
    Wie sähe es in umgekehrter Richtung aus? Also dass man eine Fehlermeldung in ein File speichert?
    Ich meine, klar, man könnte so beginnen:

    void
    logfile::log(std::string message_)
    

    und schon hat man die Mitteilung.
    Für die Zeit gibt es doch Methoden aus der Bibliothek, oder?
    Aber wie sähe eine mögliche Speicherung in einem file aus?

    Für die aktuelle Uhrzeit gibt es die Funktionen aus der <ctime> - hier wäre eine Kombination aus time() und localtime() der richtige Ansatz. Anschließend kannst du die Inhalte des struct tm zusammen mit der Meldung in ein record-Objekt packen und über den oben definierten Ausgabe-Operator in die Datei schreiben.



  • Wäre glaube ich alles einfacher würdest du XML als Format für deinen Log nehmen.

    < tag name="log vom xx.xx.xx" größe="xxx" >
        < event zeit="11:29:30" >
            Methangas entweicht durch Achterdeck!
        < /event >
    < /tag >
    


  • AP0LL0 schrieb:

    Wäre glaube ich alles einfacher würdest du XML als Format für deinen Log nehmen.

    < tag name="log vom xx.xx.xx" größe="xxx" >
        < event zeit="11:29:30" >
            Methangas entweicht durch Achterdeck!
        < /event >
    < /tag >
    

    lol 👍 🤡


Anmelden zum Antworten