Bis zum Ende einer Datei lesen und dann stoppen



  • Vielen Dank Belli,

    also hab ich in der while Loop dann die ersten 512 bytes zur Verfügung und muss nicht noch einmal in der Loop in den Buffer lesen? Baue ich in die while loop nun ein fwrite statement ein, so wird der Inhalt einmal geschrieben, baue ich fwrite 2 mal ein, so würde der Buffer 2 mal geschrieben werden? Nur fürs Verständnis. In meinem Code habe ich nen schönen Segmentation Fault und bin bisher nocht nicht drauf gekommen.



  • Belli schrieb:

    Wahrscheinlich wäre die Abbruchbedingung besser
    ... == 512 * sizeof(BYTE)

    Die Abbruchbedingung selbst muss hier natürlich

    ... != 512
    

    heißen, weil fread die Anzahl der gelesenen Blöcke rückgibt, also üblicherweise so

    size_t gelesen;
    while( gelesen=fread(buffer, sizeof(BYTE), 512, card) )
    {
      if( gelesen==512 )
      {
        ...  /* vollständig gelesener Block */
      }
      else
      {
        ...  /* nicht vollständig gelesener Block ( letzter Block vor Dateiende oder vor Lesefehler ) */
      }
    }
    


  • Storms schrieb:

    also hab ich in der while Loop dann die ersten 512 bytes zur Verfügung

    Nur beim ersten Mal. Beim zweiten Durchlauf hast Du die zweiten 512 Byte der Datei usw.



  • Wutz schrieb:

    Belli schrieb:

    Wahrscheinlich wäre die Abbruchbedingung besser
    ... == 512 * sizeof(BYTE)

    Die Abbruchbedingung selbst muss hier natürlich

    ... != 512
    

    heißen, weil fread die Anzahl der gelesenen Blöcke rückgibt, also üblicherweise so

    size_t gelesen;
    while( gelesen=fread(buffer, sizeof(BYTE), 512, card) )
    {
      if( gelesen==512 )
      {
        ...  /* vollständig gelesener Block */
      }
      else
      {
        ...  /* nicht vollständig gelesener Block ( letzter Block vor Dateiende oder vor Lesefehler ) */
      }
    }
    

    Das verstehe ich nicht so ganz. Solange der Buffer 512 Blöcke liest soll die while Funktion laufen, und sobald es weniger sind soll sie stoppen. Also müsste while(fread(buffer, sizeof(BYTE), 512, card) == 512 * sizeof(BYTE)) doch richtig sein?

    Übrigens bekomme ich einen Segmentation Fault, und der buffer ist irgendwie auch leer wenn ich ihn mir mit GDB anzeigen lasse nach der ersten iteration.

    Sagt euch die backtrace Meldung etwas?

    #0 0xb7e58430 in _IO_fwrite (buf=0xbfffef90, size=1, count=512, fp=0xbffff018) at iofwrite.c:43
    #1 0x080488f4 in main () at recover.c:89



  • Storms schrieb:

    Das verstehe ich nicht so ganz. Solange der Buffer 512 Blöcke liest soll die while Funktion laufen, und sobald es weniger sind soll sie stoppen.

    Guck mal hier http://www.cplusplus.com/reference/cstdio/fread/
    Da findest du u. a. die Deklaration von fread:

    size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

    Die Funktion liefert die Anzahl der eingelesenen Elemente, wobei jedes Element die Größe size hat.

    Storms schrieb:

    Also müsste while(fread(buffer, sizeof(BYTE), 512, card) == 512 * sizeof(BYTE)) doch richtig sein?

    Das kann nur klappen, wenn 1 == sizeof(BYTE) ist (was in deinem Fall wohl zufällig der Fall sein dürfte).
    Du weißt aber so der so nicht wie viele Bytes beim letzten fread gelesen wurden,
    also schreibst du besser:

    while((gelesen=fread(buffer, sizeof(BYTE), 512, card)) == 512)...
    

    wobei die 512 besser in einer Variable oder als Makro definiert sein sollte, weil hart gecodete Werte pfui sind.

    Storms schrieb:

    Übrigens bekomme ich einen Segmentation Fault, und der buffer ist irgendwie auch leer wenn ich ihn mir mit GDB anzeigen lasse nach der ersten iteration.

    Zeig doch mal die Deklaration von buffer und von card.



  • Da wir nicht wissen ob buffer richtig deklariert ist würde ich hier die Abstuzursache vermuten.

    die Beiden Parameter size und count geben die Blockgrösse und die maximale Anzahl der Blöcke an.
    Je nachdem wie man die Parameter nutzt bekommt man entweder die Anzahl der Blöcke
    oder z.B. die Anzahl gelesener Bytes.

    Wenn fread weniger gelesen hat als erwartet ist entweder die Datei zu Ende oder
    es ist ein Fehler aufgetreten. Fehlerusache siehe feof() oder ferror().

    EDIT: zu spät 🙂



  • Danke euch beiden. Zum Hintergrund. Ich habe gerade erst mit C angefangen und mache einen Online Kurs parallel zu meinem Business Master im Ausland. Daher sind noch nicht ganz soviele Grundkenntnise vorhanden 😉

    Es kommt jetzt übrigens kein Segmentation Fault mehr, das Program produziert allerdings auch keine jpgs. Ich habe mal wieder GDB laufen lassen und scheinbar wird die jpg Funktion nie getriggert. Im ersten Durchlauf enthält der Buffer das folgende:

    '\000' <repeats 80 times>, "http://youtu.be/oHg5SJYRHA0", '\000' <repeats 404 times>

    Im zweiten und allen folgenden:

    '\000' <repeats 511 times>

    Meinen Buffer deklariere ich so:

    typedef uint8_t  BYTE;
    

    vor main

    BYTE buffer[512];
    

    in main

    Hier eine zwischenfrage die mir gerade eingefallen ist. Wieso eigentlich nicht 511 als Zahl? Der Buffer ist ja ein array, sollte also bei 0 starten. Oder ist am Ende jeden Buffers auch noch ein \0?

    Hier die card Deklaration:

    FILE* card = fopen("card.raw", "r");
    	if (card == NULL)
    	{
    		printf("Could not open card.raw");
    		fclose(card);
    		return 1;
    	}
    

    Danke!



  • die deklaration des buffers ist okay.

    Storms schrieb:

    Wieso eigentlich nicht 511 als Zahl?

    Geht schon, wenn du 511 BYTE-Elemente willst, dann mit einem Index von 0 bis 510.
    Bei 512 BYTE-Elementen geht der Index von 0 bis 511.
    Allgemein geht der Index eines Arrays mit n Elementen(n > 0) von 0 bis n-1.

    Storms schrieb:

    Oder ist am Ende jeden Buffers auch noch ein \0?

    Nein.



  • Alles klar, danke. Eine Idee warum mein Buffer so seltsame Sachen enthält?



  • ich habe keine ahnung was gdb ist aber ich vermute, dass
    diese seltsamen "sachen" in deiner datei card.raw stehen.



  • GDB ist ein debugger den ich unter linux benutze. Die card.raw Datei enthält jpgs, die ich wiederherstellen muss. Daher ist der Inhalt doch ein wenig komisch.



  • um zu überprüfen ob deine einlesefunktion richtig funktioniert,
    kannst du z.b. eine textdatei einlesen und den inhalt des buffers mit dem datei-inhalt vergleichen.


Anmelden zum Antworten