Reputation: 12251
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:
fread
to read all the characters when using uint16_t
(but without the repeated datum of the last example)?uint16_t
? Shouldn't it be 0x6162
and 0x6364
?Upvotes: 3
Views: 1152
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
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