Binärdaten aus Datei auslesen



  • irgendwas != was anderes

    ergibt true oder false.
    Das wird zu 1 oder 0 ausgewertet, und das wird dann als Index in das Array verwendet.



  • bisschen "Strange" für mich



  • goto next1;
    

    wird ausgeführt, wenn byteFeld[1] != 0 ist.
    Das ist natürlich totaler Unsinn, aber der Frager ist von seinem Unsinn weiterhin überzeugt.



  • Schaun wir mal:

    if (byteFeld[einzelneZeichen != fileSize])
    

    Wir haben eine if-Anweisung. Die braucht eine Bedingung (zwischen den runden Klammern)
    Diese Bedingung besteht aus einer Variablen.
    Diese Variable ist ein Arrayelement, auf die mit einem Index zugegriffen wird.
    Dieser Index wiederum ist das Ergebnis eines Vergleichs.

    einzelneZeichen != fileSize ist meistens wahr und somit 1
    Beim letzten Durchlauf der while-Schleife ist aber einzelneZeichen gleich fileSize und somit die Bedingung unwahr und somit 0. (Das liegt an dem inkrement bei der Zeile mit dem fgetc )

    Es wird somit meist auf das Arrayelement byteFeld[1] zugegriffen. Dessen Wert wird genommen und als Bedingung verstanden. Ist der Wert Null ist es unwahr. Ist er ungleich Null, dann ist er wahr.
    Davon hängt also ab, ob der if-Zweig ausgeführt wird oder nicht.
    Nochmal kurz: Wenn der Inhalt von byteFeld[1] != 0 ist, wird das goto ausgeführt.
    Egal ob byteFeld[1] schon gelesen wurde oder nicht.

    Durch das inkrement beim fgetc wird dann ja auch auf ein Element verwiesen, das noch gar nicht eingelesen ist.

    Der Trick dahinter entzieht sich meiner Kenntniss ( ich habe allerdings auch noch kein MCU-Assembler gemacht)



  • unsure110 schrieb:

    bisschen "Strange" für mich

    Es ist korrektes C und man kann es (wenn man es kann) sogar lesen.
    Darum compiliert das ja auch.
    Aber

    Wutz schrieb:

    Das ist natürlich totaler Unsinn,

    was nach sehr, sehr zurückhaltend ausgedrückt ist.

    ~Real Programmer can write FORTRAN programs in any language.
    (Ed Post, Real Programmers Don't Use Pascal, 1982)~



  • Hallo,

    Mir kommt nur spanisch vor, dass bei fget_c_() das
    letztere 'c' _c_har bedeuten koennte.
    Wie ist das jetzt, bedeutet das 'c' tatsaechlich 'char'
    oder handelt es sich hier um eine Verwirrung/Verwechslung
    meinerseits?

    Die Daten im Feld sind jedenfalls different, als
    die 8Bit bzw 1Byte Daten im Hex-Editor bei 'Blink.bin'.

    Ich wuerde euch ja gerne 'Blink.bin' und den kleinen
    Hex-Editor anhaengen, jedoch ist hier keine
    Anhaenge-Button.

    Viele Gruesse, Tomator



  • Es ist korrektes C und man kann es (wenn man es kann) sogar lesen.

    Hmm, ok, aber das macht man doch nicht wirklich so ?? Ich hatte irgendeinen "Trick" dahinter vermutet der mir unbekannt ist , aber dem ist wohl nicht so.
    Naja, wieder was gelernt??



  • Tomator schrieb:

    Mir kommt nur spanisch vor, dass bei fget_c_() das
    letztere 'c' _c_har bedeuten koennte.
    Wie ist das jetzt, bedeutet das 'c' tatsaechlich 'char'
    oder handelt es sich hier um eine Verwirrung/Verwechslung
    meinerseits?

    Der 8-bit Datentyp heißt in C halt 'char' und nicht 'Byte'.



  • Tomator schrieb:

    Die Daten im Feld sind jedenfalls different, als
    die 8Bit bzw 1Byte Daten im Hex-Editor bei 'Blink.bin'.

    Wie auch immer du die Daten aus dem Feld vergleichst.

    Deine gesammte Einlesroutine ist genau so krude, wie dieser sinnfreie Vergleich den ich beschrieben habe.

    Beim einlesen machst du schon Fehler.
    Die wurden dir aber schon genannt.



  • Wenn ich mit fgetc() ein Byte beispielsweise
    auslese, was kommt dabei heraus, ein 'interpretierte
    ASCII Zeichen' das wiederum mit (Byte) gecastet
    werden muss (und dabei natuerlich ein anderer Wert
    herauskommt als das uerspruenglichen BinaerByte)
    oder habe ich das falsch verstanden,

    Bitte seit so lieb und helft mir dabei,

    Viele Gruesse, Tomator



  • Das fgetc liefert dir einen int .

    Aus der man-page:

    fgetc() liest das nächste Zeichen von stream und gibt es als ein unsigned char gecastet in einem int zurück, oder EOF bei Dateiende oder Fehler.

    Wenn der Rückgabewert also nicht EOF ist, dass lässt er sich verlustfrei wieder zurück in einen char casten. Dieser char umfasst genau ein Byte (=8 Bit) aus der Datei. (Keine Interpretation oder Veränderung.)

    Du kannst ja ein einfaches Programm erstellen, was nur die Datei öffnet und das erste Zeichen einliest und ausgibt. Das sollte, wenn du es richtig machst, mit dem ersten Zeichen aus dem Hexeditor übereinstimmen.



  • Wie du dann alles auf einmal ohne VLA einliest, kannst du bei fread nachsehen:
    http://www.cplusplus.com/reference/cstdio/fread/



  • Hallo,

    Ich habe alles moegliche mit fread(...) probiert.
    Es gibt mir 1.) das 'falsche' 2.) immer nur das
    selbe Zeichen aus.

    Gruss, Tomator


  • Mod

    Dann wirst du wohl etwas falsch gemacht haben. Welche andere Art von Antwort erwartest du nach solch einer Frage? Die Funktionen der Standardbibliothek funktionieren jedenfalls ganz sicher so wie beschrieben.



  • Hallo,

    Was habe ich denn falsch gemacht?
    Ich komme nicht dahinter.
    Bitte sage mir das einmal.

    Gruss, Tomator



  • Tomator schrieb:

    Was habe ich denn falsch gemacht?

    Du hast deinen fehlerhaften Code nicht gepostet.

    Ein minimales, compilierbares Beispiel, dass den Fehler enthält.



  • Hallo,

    Der Code scheint jetzt zu funktionieren.
    Trotzdem poste ich einmal die Codeteile
    die fuer das funktionieren verantwortlich
    sind:

    Interessant ist jedoch, dass es bei zB Byte '94' sieben
    "F" en vorher anhaengt. Also 'FFFFFF94' .Auch bei anderen
    aehnlichen Werten.
    Wieso dies?

    //Template für alle Programme
    #include <windows.h>  //benötgte Standard Headerdatei
    #include <ios>     //Required for streamize
    #include <iostream>//Dateien fuer das Oeffnen einer Standart-Datei
    #include <istream> 
    #include <fstream>
    
    using namespace std;
    
    #include <conio.h>  //Wichtig fuer die '_kbhit()' Funktion
    					 //für Windows
    #include <stdio.h>	 //für Linux, (auch um bei Windows Dateien zu oeffnen)
    #include <stdlib.h>   //für Linux (auch um bei Windows Dateien zu oeffnen)
    
    FILE  *fileZeiger = 0; //War auf ''File'' fuer die GANZE Datei, doch ich will
                                     //ja Byteweise die Datei 'zerstückelt' bis zum Ende ausgeben.
    long fileSize;///////////Groesse der File
    
    BYTE *buffer;
    
    int zaehler = 0; //Increment Variable fuer das Feld laden
    
    int main ()
    {
    
    DWORD/* LPDWORD */ BytesWritten = 0;/*war 'BytesWritten'*///Variable des Datentyps DoubleWord 
                           //Braucht es das ueberhaupt, wenn der Zeiger bereits deklariert ist?
    
    printf("\n Vor dem oeffnen der Datei ''BLINK.(!)BIN(!)''\n");
    printf("\n");
    system("Pause");
    printf("\n");
    
    fileZeiger = fopen("C:\\Schreiben an c++ Forum Binaer\\Posting02\\BLINK.BIN","r+b");// "r" wie read, "b" wie binary 
    
    if (fileZeiger == NULL)
        {
            printf("\n Fehler beim oeffnen der Datei\n");
            system("Pause");
            goto ende;
        }
        else
        {
            printf("\n BIN-Datei erfolgreich geoeffnet!\n\n");
            system("PAUSE");
        }
    
    fseek(fileZeiger, 0L, SEEK_END);//fileZeiger bis zum Ende lesen
    
    fileSize = ftell(fileZeiger);
    
    fseek(fileZeiger, 0L, SEEK_SET);
    
    int result; 
    
    //Zurueck'suchen' bis zum Anfang file
    
      while( true )
        {
         //////////byteFeld[einzelneZeichen++] = (BYTE) fgetc(fileZeiger);//Einzelne Bytes aus dem File über den "fileZeiger" 
                                                                        //holen und in das Feld 'byteFeld[]' geben
         // copy the file into the buffer:
      ////////result = fread (buffer,1,fileSize,fileZeiger);
      result = (char)fgetc(fileZeiger);
    
       printf("\n byteFeld[einzelne 8Bit Zeichen]: %X ", result++);//der '%X' Platzhalter steht für HeXadezimal
       printf("  ,Inhalt zaehler : %d",zaehler);
       printf("\n\n");
       system("PAUSE");
    
         if(zaehler >= fileSize)
                  {
                        break;
                  }
    
       zaehler++;           
    
      }     
    
       ende:
       printf("\n\nEnde Programm\n\n");     
       system("Pause");
       return 0;             
    
    }
    


  • 😮 Das ist ja immer noch der gleiche Schrott. Hätte ich bloss nicht gefragt.

    Das mit den FF liegt daran, das du da einen negativen Wert hast. Daran bist du aber selber schuld.

    result = (char)fgetc(fileZeiger); // was soll der cast auf char?
    


  • Was dein Programm derzeit machen soll (ohne goto, ohne postinkrement des eingelesenen Wertes, mit richtiger Abbruchbedingung, vernünftiger Mode bei fopen)

    #include <stdio.h>
    int main ()
    {
      FILE * pFile;
      int c;
      int n = 0;
      char fname[] = "BLINK.BIN";
    
      pFile=fopen (fname,"rb");
      if (pFile==NULL) 
        perror ("Error opening file");
      else
      {
        while ((c = fgetc(pFile)) != EOF)
        { printf("%5d : %02x\n", n, c);  // Mit Zeichenausgabe: printf("%5d : %02x %c\n", n, c, c);
          n++;
        } 
        fclose (pFile);
        printf ("The file contains %d characters.\n",n);
      }
      return 0;
    }
    

    Und was du eigentlich vor hast (einlesen in den Speicher) kannst du bei fread nachlesen: http://www.cplusplus.com/reference/cstdio/fread/



  • Hallo,

    DirkB:
    Bla, bla, bla, bla.
    ES IST MIR VOELLIG EGAL WAS IHR VON MIR DENKT,
    UND WIE DER RESTLICHE CODE AUSSIEHT!

    Der Code geht jetzt jedenfalls korrekt, es
    werden die Binaerdaten korrekt ausgelesen.

    Mehr wollte ich jedenfalls von euch
    Jungs und Maedels nicht!

    Jedenfalls dankeschoen, und auf wiedersehen!

    Gruss Tomator


Anmelden zum Antworten