Maury Markowitz
Maury Markowitz

Reputation: 9283

fread returns no data in my buffer in spite of saying it read 4096 bytes

I'm porting some C code that loads sprites from files containing multiple bitmaps. Basically the code fopens the file, fgetcs some header info, then freads the bitmap data. I can see that the fgetcs are returning proper data, but the outcome of the fread is null. Here's the code - fname does exist, the path is correct, fil is non-zero, num is the number of sprites in the file (encoded into the header, little-endian), pak is an array of sprites, sprite is a typedef of width, height and bits, and new_sprite inits one for you.

FILE *fil;
uint8 *buffu;
uint8 read;
int32 x,num;
int32 w,h,c;

fil = fopen(fname, "rb");
if (!fil) return NULL;

num = fgetc(fil);
num += fgetc(fil)*256;
if (num > max) max = num;

for (x=0;x<max;x++) {
    // header
    w=fgetc(fil);
    w+=fgetc(fil)*256;
    h=fgetc(fil);
    h+=fgetc(fil)*256;
    fgetc(fil); // stuff we don't use
    fgetc(fil);
    fgetc(fil);
    fgetc(fil);
    // body
    buffu = (uint8*)malloc(w * h);
    read=fread(buffu,1,w*h,fil);
    pak->spr[x]=new_sprite(w,h);
    memcpy(pak->spr[x]->data, buffu, w*h);
    // done
    free(buffu);
}

I've stepped through this code line by line, and I can see that w and h are getting set up properly, and read=4096, which is the right number of bits. However, buffer is "" after the fread, so of course memcpy does nothing useful and my pak is filled with empty sprites.

My apologies for what is surely a totally noob question, but I normally use Cocoa so this pure-C file handling is new to me. I looked all over for examples of fread, and they all look like the one here - which apparently works fine on Win32.

Upvotes: 1

Views: 1025

Answers (2)

user3121023
user3121023

Reputation: 8286

Since fgetc seems to work, you could try this as a test

int each;
int byte;

//body
buffu = malloc(w * h);
for (each = 0; each < w*h; each++) {
    byte = fgetc(fil);
    if ( byte == EOF) {
        printf("End of file\n");
        break;
    }
    buffu[each] = (uint8)byte;
    printf ("byte: %d    each: %d\n", byte, each);
}
pak->spr[x]=new_sprite(w,h);
memcpy(pak->spr[x]->data, buffu, w*h);
// done

Upvotes: 1

unwind
unwind

Reputation: 399989

You say:

However, buffer is "" after the fread, so of course memcpy does nothing useful

But that is not true at all. memcpy() is not a string function, it will copy the requested number of bytes. Every time. If that isn't "useful", then something else is wrong.

Your buffer, when treated as a string (which it is not, it's a bunch of binary data) will look like an empty string if the first byte happens to be 0. The remaining 4095 bytes can be whatever, to C's string printing functions it will look "empty".

Upvotes: 1

Related Questions