Protokoll in Textdatei schreiben mit StringListe.



  • Moin erst mal.

    ich möchte gerne ein Programm durch ein protokoll erweitern. Dieses soll halt wenn
    Werte neu Eingegben oder irgednwie verändert werde in eine textdatei geschrieben werden.

    Problem:

    Wenn die logzeile geschrieben wird, wird sie immer wieder überschrieben. ich möchte das sie aber an der letzte Position anfängt z.b

    Uhrzeit2 neue wert 123
    Uhrzeit2 neue wert 123
    Uhrzeit2 neue wert 123
    Uhrzeit2 neue wert 123
    usw..

    ich habe mir schon überlegt die textdatei in ne andere StringList zu laden und dann halt da weiter zuschreiben und jedesmal diese dann in die textdatei zu shcreiben. aber das ergibt das problem wenn die textdatei einaml zugroß ist..hab ich das Problem mit dem speicher..

    diese war nur ein test:

    const AnsiString FileName1 = "D:\\test.log";
    TStringList *TestListe = new TStringList;
    AnsiString t=DateTimeToStr(Now());
    TestListe->Add(t+ "\t" +LbProg->Caption+ "\t" +"Prüfungsergebnis:"+" "+dMean+"\t"+"Grenzwert MIN:"+" "+dMin+"\t"+"Grenzwert MAX:"+" "+dMax);
    TestListe->SaveToFile(FileName1);
    

    dieses beispiel zeigt wie die Zeile immer wieder überschrieben wird 😞



  • öh...
    ich würd sagen, du musst mit ner for die einzelnen werte/zeilen ermitteln und in der for dann fopen("dateiname.log","a+") benutzen. a+ ist nämlich an das ende der file schreiben.

    mein tipp, ich bin gespannt auf eure 😃



  • Hi,

    ich bin ja nicht DER Crack hier, aber damit sollte es (im ++ style) gehen:

    include <fstream.h>
    
    void main()
    {
      string fname="xyz.log";
      ofstream targetfile(fname.c_str(), [b]ios::app[/b]);
      if (!targetfile)
      {
        cout << "Zieldatei: "<< fname.c_str() << " konnte nicht geoeffnet werden.\n";
      }
    
      targetfile <<"blabla"<<endl;
    
      targetfile.close();
    }
    

    ios::app : All the date you write, is put at the end of the file. It calls ios::out
    ios::ate : All the date you write, is put at the end of the file. It does not call ios::out
    ios::trunc : Deletes all previous content in the file.

    mfg
    robi1806



  • gibt es da keien andere möglichkeit ?



  • Was stört dich denn daran?
    Es ist doch nicht sonderlich kompliziert oder viel Code.
    Und wenns an dem AnsiString liegt, den kannst du damit ja auch benutzen.



  • Naja... mir gefällt daran nicht, dass es so alt aussieht... :p

    Hab das gefunden, ist auch viel mehr Code 😉 :
    http://www.bytesandmore.de/rad/cpp/snipp/sc01008.php



  • Also die Lösung von robi1806 halte ich recht sinnvoll. Ich finde TStringList zwar gut und benutze sie häufig, aber für Logging
    scheint mir die Klasse nicht sonderlich geeignet. Eigentlich sind Stringlisten dafür da Strings in Listen zu packen (sinnreich)
    und bieten halt sozusagen nebenbei noch Methoden zum Laden aus und zum Speichern in Dateien.

    Wenn Du aber unbedingt eine Stringliste verwenden willst, müsstest Du die Liste beim Programmstart erstellen und, falls an einen
    bestehenden Log angehängt werden soll, die bestehende Log-Datei geladen werden:
    (Ungetestet)

    const AnsiString FileName1 = "D:\\test.log";
    // Irgendwo - z.B. im Konstruktor des Hauptformulars
    TStringList *TestListe = new TStringList;
    TestListe->LoadFromFile(FileName1);
    

    Um neue Logeinträge an die Datei anzuhängen, musst Du nach jedem Add()-Aufruf die Stringliste wieder speichern - am besten
    innerhalb einer Methode:
    (Ebenfalls ungetestet)

    void writeToLog(AnsiString ALogString)
    {
      TestListe->Add(ALogString);
      TestListe->SaveToFile(FileName1);
    }
    

    Wenn man aber viele Log-Einträge hat (bei uns kann die Log-Datei schnell mehrere MB groß sein), dann vermute ich, dass Du einen
    recht großen Overhead durch die Stringliste mit herumschleppst.

    Gruß,

    Alexander



  • |23| schrieb:

    ich habe mir schon überlegt die textdatei in ne andere StringList zu laden und dann halt da weiter zuschreiben und jedesmal diese dann in die textdatei zu schreiben. aber das ergibt das problem wenn die textdatei einaml zugroß ist..hab ich das Problem mit dem speicher..

    Ist nicht das damit gemeint?



  • @Alexander

    ich weiß nicht ob du es gelesen hast:

    const AnsiString FileName1 = "D:\\test.log";
    TStringList *TestListe = new TStringList;
    AnsiString t=DateTimeToStr(Now());
    TestListe->Add(t+ "\t" +LbProg->Caption+ "\t" +"Prüfungsergebnis:"+" "+dMean+"\t"+"Grenzwert MIN:"+" "+dMin+"\t"+"Grenzwert MAX:"+" "+dMax);
    TestListe->SaveToFile(FileName1);
    

    Das bekomme ich ja auch hin und nach diesen Eintrag schaut meien log dann so aus:

    Log datei nicht cpp:

    14.09.2004 14:32:16	Progr.Nr.:	Prüfungsergebnis: 0	Grenzwert MIN: -10	Grenzwert MAX: 10
    

    und es soll immer neue Zeilen schreiben nicht die erst überschreiben was er ja noch tut. ich könnte das ja machen indem ich Die Datei einfach in ne STringListe einlese..

    ja alles schön und gut ist blos meine logdatei nach 1 Jahr ca. 100 MB groß gibt es da schon Probleme mit speed/speicher.

    Also suche ich ne möglich keine dieses nicht zu tun ich weiss das ich das irgednwie mit fopen/fwrite usw. machen muss aber noch raf ich das nicht 😞

    robi1806 Beispiel versteh ich leider noch ned ganz...was heisst ganz überhaupt ned 😃 😞

    Edit1:

    optest = fopen("D:\\test.log","a");
    

    damit öffne ich das test.log und durch das a wird am dateiende geschrieben
    oder ?



  • ok, dann sag das doch 🙂

    include <fstream.h> //filestreams werden verwendet
    
    string fname="xyz.log";
    //enthält dateiname, kannst statt dem string auch char[] nehmen. 
    
    ofstream targetfile(fname.c_str(), ios::app);
    //erzeugt neuen output filestream in die mit fname angegebene datei
    //falls die Datei besteht wird angehängt, app=append
    
    targetfile <<"blabla"<<endl; 
    //schreibt text in die Datei. Statt "blabla" kannst du strings, ints, chars,... nehmen
    // endl schreibt einen Zeilenumbruch, kannst auch "/n" dafür nehmen
    // "/t" ist ein Tab
    
    // schließt den Filestream
    targetfile.close(); 
    }
    


  • Danke erst mal

    {
      String fname="bla.log";
      ofstream targetfile(fname.c_str(), ios::app);
      if (!targetfile)
      {
        ShowMessage("dsdasdsa");
      }
      TStringList *TestListe = new TStringList;
      AnsiString t=DateTimeToStr(Now());
    
      targetfile << TestListe->Add(t+ "\t" +LbProg->Caption+ "\t" +"Prüfungsergebnis:"+" "+g_ipCS_StoC.dMean+"\t"+"Grenzwert MIN:"+" "+g_sDataSet.sNominals.dMin+"\t"+"Grenzwert MAX:"+" "+g_sDataSet.sNominals.dMax) << endl;
    
      targetfile.close();
    }
    

    so bekomme ich immer den Wert 0 eingetragen nee idee oder wird das nix so die StringListe da reinzubekommen.

    achja und die Zeile Geht ja nicht :

    cout << "Zieldatei: "<< fname.c_str() << " konnte nicht geoeffnet werden.\n";
    

    ist aj keien konsolen Application



  • Was soll die Stringliste denn da drin? TStringList::Add() hat nichts damit zu tun, Strings an eine Datei anzuhängen.

    |23| schrieb:

    TStringList *TestListe = new TStringList;
      targetfile << TestListe->Add(t+ "\t" +LbProg->Caption+ "\t" +"Prüfungsergebnis:"+" "+g_ipCS_StoC.dMean+"\t"+"Grenzwert MIN:"+" "+g_sDataSet.sNominals.dMin+"\t"+"Grenzwert MAX:"+" "+g_sDataSet.sNominals.dMax) << endl;
    

    Stattdessen könntest Du auch einfach schreiben:

    targetfile << t+ "\t" +LbProg->Caption+ "\t" +"Prüfungsergebnis:"+" "+g_ipCS_StoC.dMean+"\t"+"Grenzwert MIN:"+" "+g_sDataSet.sNominals.dMin+"\t"+"Grenzwert MAX:"+" "+g_sDataSet.sNominals.dMax << endl;
    

    Dann hast Du vielleicht auch keine 0 mehr drin stehen. Wenn Du Dir mal in der BCB-Hilfe die Erläuterungen zu Add() anschauen würdest,
    könntest Du auch verstehen, warum bei Dir eine 0 auftaucht.

    Gruß,

    Alexander



  • jow hast recht war nen Fahler mit der StringList

    aber das mit der was du sagst geht auch ned den cout << kann kein ANsiString anhemen :

    [C++ Fehler] MAIN.CPP(727): E2094 'operator<<' ist im Typ 'ofstream' für Argumente des Typs 'AnsiString' nicht implementiert



  • Du musst an die Ansistrings noch ein .c_str() hängen, dann gehts

    AnsiString text="bla";
    oFile<<text.c_str()<<endl;
    


  • Wobei sich dazu noch folgender Artikel empfiehlt:
    http://www.c-plusplus.net/forum/viewtopic.php?t=39296

    -junix



  • @|23|

    |23| schrieb:

    @Alexander

    ich weiß nicht ob du es gelesen hast:

    const AnsiString FileName1 = "D:\\test.log";
    TStringList *TestListe = new TStringList;
    AnsiString t=DateTimeToStr(Now());
    TestListe->Add(t+ "\t" +LbProg->Caption+ "\t" +"Prüfungsergebnis:"+" "+dMean+"\t"+"Grenzwert MIN:"+" "+dMin+"\t"+"Grenzwert MAX:"+" "+dMax);
    TestListe->SaveToFile(FileName1);
    

    Das bekomme ich ja auch hin und nach diesen Eintrag schaut meien log dann so aus:

    Log datei nicht cpp:

    14.09.2004 14:32:16	Progr.Nr.:	Prüfungsergebnis: 0	Grenzwert MIN: -10	Grenzwert MAX: 10
    

    und es soll immer neue Zeilen schreiben nicht die erst überschreiben was er ja noch tut. ich könnte das ja machen indem ich Die Datei einfach in ne STringListe einlese..

    Nur dass du das

    TestListe->LoadFromFile(FileName1);
    

    vor dem Hinzufügen vergessen hast und somit immer wieder das alte überschreibst



  • und was die wachsende Größe angeht...

    Ich hab' ein Programm das pro Tag bis zu mehrere MB in das Logfile schreibt. Ich hab das dann so gelöst, dass ich jeden Tag ein neues Logfile beginne und das Datum im Dateinamen verwende (20040914.log). Dieses Logfile wird beim ersten Start des Programms an einem Tag neu erzeugt. Alle Logfiles älter als 30 Tage werden beim ersten Programmstart am Tag gelöscht...



  • Joe_M. schrieb:

    und was die wachsende Größe angeht...

    Ich hab' ein Programm das pro Tag bis zu mehrere MB in das Logfile schreibt. Ich hab das dann so gelöst, dass ich jeden Tag ein neues Logfile beginne und das Datum im Dateinamen verwende (20040914.log). Dieses Logfile wird beim ersten Start des Programms an einem Tag neu erzeugt. Alle Logfiles älter als 30 Tage werden beim ersten Programmstart am Tag gelöscht...

    hast du den SourceCode noch? würde mir den gerne mal angucken..

    @Linnea

    danke für den Tip 👍 😉



  • @|23|: Mail mir mal Deine E-Mail Adresse über den Link in meinem Profil. Kann aber 1-2 Tage dauern Dir das dann zu mailen. Bin im Moment etwas im Streß...



  • @Joe_M. ok danke, aber das ist wirklich zuspät. hmm schade 😞 naja ... wenn du schon nicht dazu kommst mir das gleich zu schicken zeit mir nen paar tips zu geben wie ich das mit der Funktion machen das jeden Tag eine neue Datei erstellt wird ?!


Log in to reply