ian
ian

Reputation: 12251

fread loop doesn't read all bytes, and why are the bytes reversed?

I have a file with some test data in it, "abcde". I want to read the data from it into a uint16_t buffer a byte at a time, (I'm not interested in the meaning of the data as such, just its binary representation for a checksum) but the final "e" isn't being read:

FILE *fp = fopen(filepath, "rb");
uint16_t buffer[1];
while ( fread( buffer, sizeof(uint16_t), 1, fp ) != 0 ) {
  printf("0x%x\n", *(buffer) );
}

That outputs:

0x6261
0x6463

If a uint8_t type is used then the output is:

0x61
0x62
0x63
0x64
0x65

I tried reversing the size and nmemb arguments to fread (e.g. while ( fread( buffer, 1, 2, fp ) != 0 ) but got:

0x6261
0x6463
0x6465

Which is probably the least help of all!

This leaves me with 2 main questions:

  1. How should I call fread to read all the characters when using uint16_t (but without the repeated datum of the last example)?
  2. Why are the bytes reversed when using uint16_t? Shouldn't it be 0x6162 and 0x6364?

Upvotes: 3

Views: 1152

Answers (2)

PkP
PkP

Reputation: 438

fread() always reads complete records. And as the size of uint16_t is 2 bytes in a machine whose byte size (CHAR_BIT) is 8 bits, each call to fread() reads multiples of 2 bytes in your code.

You can read the individual bytes for example with fgetc() like this:

FILE *f;
uint16_t array[5];
void foo() {
    int i;
    for (i=0; i<5; i++) {
        array[i] = fgetc(f);
    }
}

The bytes are "reversed" because you're likely running in a little-endian machine.

Upvotes: 3

David Schwartz
David Schwartz

Reputation: 182829

The bytes aren't reversed. You're misreading the output. On your platform, a uint16 value of 0x1234 means an 0x34 followed by an 0x12. There's no one right way to store multi-byte values in memory and your platform happens to choose this way.

Don't reverse the parameters to fread. If you read a partial value, you don't want to print it. If you want to do something specific in the case where the file is not an even multiple of your data size, decide what and write code to do it.

Upvotes: 2

Related Questions