Good day. There is a binary file, the information in which is presented in the form of hexadecimal octets. Let the content of the file be: "01 31 A4 F5". It is required to read the first two bytes, and then translate into a decimal number. I do it like this:

#include<stdio.h> #include<stdlib.h> int main() { FILE *ptrFile = fopen("/path/file.bin", "rb") int *num = (int *) malloc(2); //Π²Ρ‹Π΄Π΅Π»ΠΈΠ» Π² памяти 2 Π±Π°ΠΉΡ‚Π°, ΠΏΡ€ΠΈΠ²Π΅Π» ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ ΠΊ Ρ‚ΠΈΠΏΡƒ int fread(num, 1, 2, ptrFile); //ΡΡ‡ΠΈΡ‚Ρ‹Π²Π°ΡŽ ΠΈΠ· Ρ„Π°ΠΉΠ»Π° 2 элСмСнта Ρ€Π°Π·ΠΌΠ΅Ρ€ΠΎΠΌ 1 Π±Π°ΠΉΡ‚ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π² Π±Π»ΠΎΠΊ памяти num printf("hex num is %X\n", *num); //Π²Ρ‹Π²ΠΎΠ΄ считанной ΠΈΠ½Ρ„Ρ‹ Π² hex Π²ΠΈΠ΄Π΅ printf("dec num is %d\n", *num); //Π²Ρ‹Π²ΠΎΠ΄ считанной ΠΈΠ½Ρ„Ρ‹ Π² dec Π²ΠΈΠ΄Π΅ return 0; } 

As a result, instead of getting

 hex num is 131 dec num is 305 

I get:

 hex num is 3101 dec num is 12545 

Why does fread () invert bytes and how to avoid it?

  • Check out: en.wikipedia.org/wiki/… - iksuy
  • fread() nothing to do with it, all due to the fact that x86 is a little-endian architecture, i.e. The lower digits of the number are in bytes with lower addresses. And we are used to writing numbers in big-endian (lower order on the right). Here you have a big-endian file. - avp

1 answer 1

First, you allocate 2 bytes of memory here, and you read sizeof (int) bytes, which is usually 4, but it can be another number β€” the size of int in the language is not fixed. Those. you are reading over the allocated memory, this is a mistake.

Secondly, read about Little Endian (LE) and Big Endian (BE) - two different ways of representing numbers in memory. On x86 architecture, this is always LE, so the lower byte comes first. This explains why the bytes of yours "turned over" when displayed on the screen (although they are in the same order in memory).

"Byte Order" on Wikipedia

About "how to avoid it" - it depends on what you want to get. If the goal is to show what is in the file - read into the array byte and display byte by byte.

  • My goal is to get the decimal number encoded in the first two bytes: 0131h = 305. I realized that the number I read was in memory as 31 01. It is logical to assume that when I write it to another variable (int x = * num) , this is something that will be taken into account, and as a result, x will be equal to 305 (or 0x131). But in the end, the conditions x == 305 and x == 0x131 are false, and x == 12545 and x == 0x3101 are true. It turns out that I counted the number from the file, but I cannot use it in its true meaning. So how to get a variable containing the desired decimal number. - Ruslan
  • @Ruslan, in the file you have in the first bytes is the number 0x3101 - since we have LE. Just like in the file, it will also be stored in memory - as bytes 01 31. You can read from the file into the byte array barr and get it as BE: int num = (barr[0] << 8) | barr[1]; int num = (barr[0] << 8) | barr[1]; - nzeemin
  • thank you very much, it worked. - Ruslan