Von einer Bildschirmausgabe zum abspeichern in einer Datei



  • benutz bitte den editier button oben rechts wenn du einem pot etwas hinzufügen möchstest :p

    setz mal bei fread einen breakpoint und bei fopen für die zieldatei, das klingt haargenau danach als ob dasa öffnen fehlschlägt und dein fout ins nirvana zeigt, kann auch ausm fread kommen ... setz einfach die breakpoints und wenn der debugger da steht, lass dir die werte von den varialben f, fout, DEARecord und stm anzeigen ... was mir spanisch vorkommt ist

    struct tm stm = *localtime(&DEARecord.Startzeit);

    kann das wer am rande erklären oder liegt hier evtl. ein fehler ?!

    füge mal

    if (fout == NULL) {
        int Error = GetLastError();
        printf("Fehler %d", Error); <--- breakpoint
    }
    

    nach fopen ein und setz nen breakpoint da ein wenn du dort reinstolperst kannst ja mal nach der beschreibung zu dem fehlercode schauen



  • Ja, vermutlich - schau mal genau hin, wo dieser Fehler auftritt.

    (und auch auf die Gefahr hin, mich zu wiederholen: Kontrolliere auf Fehler (z.B. beim Öffnen der Dateien))



  • Du verwendest in einem Struct, was du einlesen willst eine Union. Ist sichergestellt, dass die .pls-Datei an der Stelle, wo du unsigned char und float vereinigt hast, auch immer sizeof(float) Bytes (binär) vorhanden sind?

    EDIT: Du solltes dein Struct (sodann du denn dabei bleiben willst) nicht eins zu eins (binär) aus der Datei kopieren, sondern die Werte nacheinander explizit zuweisen (falls es sich um ein binär-Format handelt).

    Seg-Faults ließen sich einfacher vermeiden, wenn du statt char* std::string verwendest und statt diverser Arrays eben einen Container aus der STL (std::vector, std::list, std::map, etc.).

    Grüße... Heiko



  • Ok, danke erst mal am Anfang!
    Dann muss ich allerdings sagen, dass ich 60% eurer Vorschläge nicht wirklich verstanden habe.
    Ich versuch es jetzt mal der Rehei nach und schau dann mal was ich davon hinbekomme 🙂



  • nixversteher schrieb:

    ...
    Dann muss ich allerdings sagen, dass ich 60% eurer Vorschläge nicht wirklich verstanden habe....

    Zu den anderen Vorschlägen will ich nix sagen, aber meinen ersten kann ich nochmal erläutern:
    1.) Ausgeben eines Objekts (hier eines DEA_ARCHIV_TYP-Objekts) in eigene Funktion auslagern
    2.) Diese Funktion nenne ich "operator<<()" und sie wird mit "... << ..." aufgerufen (z.B. wird bei cout << "Simon" der operator<<(ostream&, char const*) als operator<<(cout, "Simon") aufgerufen.)
    3.) Diese Funktion kann man mit jedem ostream nutzen (egal, ob cout, ofstream, ...).

    Zusatz: Ich habe einen eigenen operator<<() für "struct tm*" geshrieben, weil man den immer mal gebrauchen kann.

    Gruß,

    Simon2.



  • Also, das Programm läuft, noch nicht ganz wie es soll, aber es läuft 🙂

    Ich habe jetzt eine 2 Variable mit in die Funktion Konvert() übergeben und darin den passend veränderten Dateinamen.

    Jetzt steh ich noch vor einem Problem worauf ich mir mal gar keinen Reim machen kann: Ich habe im ersten Verzeichnis, in der die nicht konvetierten Dateien stehen ca. 13700 Dateien. Die möchte ich alle Konvertiert haben, allerdings steigt mein Programm nach der 509ten Datei aus, hab ich evtl irgendwo ne Bereichsüberschreitung oder eine Variable die dann überläuft???
    Oder gibts da sonst eine erklärung für?

    Danke schon mal bis hierher!!

    using namespace std;
    
    void Konvert(const char *filename, const char *datei);
    
    #pragma pack(push,2)
    
    typedef float         FLOAT;
    typedef unsigned char UCHAR;
    typedef char          CHAR;
    typedef short int     SHORT;
    typedef time_t        DATE_TIME;
    
    typedef union _proz_wert_union {  /* Union für den Prozeßwert */
      FLOAT Wert;               /* für Analogeingänge einen Float  */
      UCHAR Zustand;            /* für Digitaleingänge einen UCHAR */
    } PROZ_WERT_UNION;          /* 4 Byte entsprechend dem größen Member */
    
    typedef struct _dea_archiv_typ { /* Bytes Bedeutung                               */
      DATE_TIME       Startzeit;      /*  4  Startzeit des Intervalls                 */
      SHORT           Millisec;       /*  2  Millisec. bei Echtzeitverarb. sonst. -1  */
      PROZ_WERT_UNION Wert;           /*  4  union für den Prozeßwert                 */
      UCHAR           Kennung;        /*  1  Kennung des archivierten Wertes          */
      CHAR            Grund;          /*  1  Archivierungsgrund                              */
    } DEA_ARCHIV_TYP;                 /* 12  Byte pro Archiveintrag                   */
    #pragma pack(pop)
    
    int main ()
    
    {
        char pathname[MAX_PATH + 1];
        char maskname[MAX_PATH + 1];
        char fullname[MAX_PATH + 1];
    
        char pfad[MAX_PATH + 1];
        char ganz[MAX_PATH + 1];
        char dat[MAX_PATH + 1];
    
        strncpy(pathname, "C:\\Osnabrueck\\DEA\\2007\\09\\", MAX_PATH);
        strncpy(maskname, pathname, MAX_PATH);
        strncat(maskname, "*", MAX_PATH);
        HANDLE fHandle;
        WIN32_FIND_DATA wfd;
    
                        fHandle=FindFirstFile(maskname,&wfd);
    
                        do
                        {
    
                           if (!( (wfd.cFileName[0]=='.') && ( (wfd.cFileName[1]=='.' && wfd.cFileName[2]==0) || wfd.cFileName[1]==0 ) ))
                           {
                             if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                             {
                               MessageBox(0,wfd.cFileName,"Folgendes Verzeichnis wurde gefunden:",0);
                               // Datei ist keine, sondern ein Verzeichnis...
    
                             }
                             else
                             {
    
                              cout << wfd.cFileName << endl;  //Namen der Dateien ausgeben
                              strncpy(fullname, pathname, MAX_PATH);
                              strncat(fullname, wfd.cFileName, MAX_PATH);
    
                              strncpy(pfad, "C:\\Osnabrueck\\DEA\\2007\\KONV\\09\\", MAX_PATH);
                              strncpy(ganz, pfad, MAX_PATH);
                              strncpy(dat, pfad, MAX_PATH);
                              strncat(dat, wfd.cFileName, MAX_PATH);
                              strncat(dat, ".txt", MAX_PATH);
    
                              Konvert(fullname,dat);
    
                              }
                              }
                              }
                         while (FindNextFile(fHandle,&wfd));
              FindClose(fHandle);
    
           cin.get();
    }
    
    void Konvert(const char *filename,const char *datei)
    {
    
                        FILE *fout = fopen(datei, "w");
                       	FILE *f = fopen(filename,  "rb");
                        	if (f) {
                         		DEA_ARCHIV_TYP DEARecord;
                           		while(!feof(f)) {
                             			fread(&DEARecord, sizeof(DEARecord), 1, f);
                                			struct tm stm = *localtime(&DEARecord.Startzeit);
    
                                   			fprintf(fout,"%02d.%02d.%04d %02d:%02d.%02d,%03d : ", stm.tm_mday
                                      				, stm.tm_mon +1
                                      				, stm.tm_year + 1900
                                      				, stm.tm_hour -2
    				                                 , stm.tm_min
    		                                       , stm.tm_sec
    
    				                                , DEARecord.Millisec > 0 ? DEARecord.Millisec : 0);
    
                                             fprintf(fout,"DEARecord: Zustand = %d, Kennung = %d, Grund = %c\n", DEARecord.Wert.Zustand
                                             , DEARecord.Kennung
                                             , DEARecord.Grund);
    
    		                               }
    
                                     fclose(f);
    
                                     }
      // cin.get();
    //return 0;
    
    }
    


  • Du solltest natürlich auch die Ausgabedatei per fclose() schließen, wenn du sie nicht mehr brauchst.

    (übrigens sehen die ganzen strncpy()-Serien im Hauptprogramm etwas unnötig aus)



  • Oh ähh, ja richtig da war was...
    Danke läuft. 👍
    Hab mit den "strncpy()-Serien" etwas rumprobiert und so läuft es am besten, und mit den wenigsten Fehlern 😃

    Danke nochmal an alle beteiligten!!



  • nixversteher schrieb:

    ...

    ...
    typedef float         FLOAT;
    typedef unsigned char UCHAR;
    typedef char          CHAR;
    typedef short int     SHORT;
    typedef time_t        DATE_TIME;
    ...
    
    int main ()
    
    {
        char pathname[MAX_PATH + 1];
        char maskname[MAX_PATH + 1];
        char fullname[MAX_PATH + 1];
        
        char pfad[MAX_PATH + 1];
        char ganz[MAX_PATH + 1];
        char dat[MAX_PATH + 1];
        
        strncpy(pathname, "C:\\Osnabrueck\\DEA\\2007\\09\\", MAX_PATH);
        strncpy(maskname, pathname, MAX_PATH);
        strncat(maskname, "*", MAX_PATH);
    ...
        strncpy(fullname, pathname, MAX_PATH);
        strncat(fullname, wfd.cFileName, MAX_PATH);
        strncpy(pfad, "C:\\Osnabrueck\\DEA\\2007\\KONV\\09\\", MAX_PATH);
        strncpy(ganz, pfad, MAX_PATH);
        strncpy(dat, pfad, MAX_PATH);
        strncat(dat, wfd.cFileName, MAX_PATH);
        strncat(dat, ".txt", MAX_PATH);
    ...
    

    😮 😮 😕
    Also DAS ist definitv überflüssig und unübersichtlich. Für sowas wurde String genommen.

    Aber ich habe den Eindruck, als wollest Du eigentlich sowieso nicht wirklich etwas lernen, sondern nur "solange fummeln, bis irgendwas irgendwie klappt"...

    Schade, hätte ich das vorher gewusst, hätte ich mir einiges an Zeit gespart.

    Gruß,

    Simon2.



  • Gut möglich, dass es überflüssig ist.
    Ich würde nicht sagen, dass ich nichts lernen wollte, aber programmieren an sich war noch nie mein Lieblingssport, und ich denke da wirst du mir zustimmen, man benötigt ein gewisses Händchen für sowas. Und genau das hatte ich noch nie, deshalb habe ich versucht das unvermeidlich nötige zu lernen bzw zu verstehen.
    Ich kann auch nicht abstreiten, dass mir persönlich es egal ist wie ein Programm im Endeffekt aussieht solange es das macht was es soll...
    Vielen Dank für deine Mühe!



  • Hi,

    das Problem ist: Je weniger Du verstehst, umso höher die Chance, dass Dein Programm doch nicht ganz das tust, was Du möchtest ... und je mehr Du versuchst, an den Symptomen rumzudoktern, umso schwerwiegender werden die Probleme, mit denen Du Dich rumschlagen musst.
    Ist eigentlich das klassische "Designphasenproblem": Wenn man in der Designphase schludert, kommt man schneller zu einem Code, der "fast" das richtige tut .... und braucht für den "kleinen Schritt von fast zu ganz" dreimal so lange wie ein vernünftiges Design gebraucht hätte.
    Außerdem hat man anschließend ein Programm, das man 1 Jahr später erst Recht nicht mehr versteht ... und deswegen bei der nächsten Änderungsanforderung wieder von vorne anfängt.

    :p 😉 😃

    Aber von derlei allgemeinphilosophischen Überlegungen abgesehen: Statt der "Binärspeicherei" solltest Du ernsthaft ein vernünftiges Protokoll in Erwägung ziehen !!

    DAS ist der Teil, der Dir wirklich ganz schnell und seeeehr heftig um die Ohren fliegt !!

    Gruß,

    Simon2.


Anmelden zum Antworten