Reputation:
I have a "funny" issue with C function fwrite
. I have an unsigned int
pointer and I want to write it into a binary file, so I've used fwrite
. But the byte in the file are written upside down. Considering size of unsigned int
(4 byte in my case), for example, if I my data is FE 45 78 D4 4C E9 EA F1
etc, I see the file contents as D4 78 45 FE F1 EA E9 4C
etc. How can I resolve this?
a little more information: when i say that byte are written in wrong order, i mean that every program i use to read the file see the byte in wrong order, bringing of course a reading error... i do not understand why only fwrite function use a different way to represent data...
more information:
i tried
fwrite(myuipointer,4,size,file);
fwrite(myuipointer,1,size*4,file);
same result. I also tried to use an unsigned char pointer that point to my data and fwrite it, no success...
Upvotes: 1
Views: 902
Reputation: 27632
Others have covered the concept of byte order in their answers, and that this is the expected behavior on a little-endian computer.
But I looked at some of your other questions, and you seem to be working with JPEG files, and my guess is that this is the problem?
JPEG files need to be portable between different types of computers, not just little-endian and big-endian, but also 32-bit and 64-bit, and so on. Therefore JPEG defines its own standard sizes and byte orders, and (if different) you need to convert your computer's internal format to the JPEG format. If you just dump the internal representation to a file, which is what fwrite does, then any program that expects the correct JPEG format will fail.
If you download the source code for a free JPEG program or library, such as libjpeg, you will see that they don't just use fread and fwrite, but have code that reads and writes each byte according to the JPEG standard.
Upvotes: 1
Reputation: 35851
This happens because your computer uses the little-endian representation of data. This means that data such as integers are stored in memory starting from the least significant byte.
Your numbers are:
FE 45 78 D4
4C E9 EA F1
Which will be represented starting from the least significant byte:
D4 78 45 FE
F1 EA E9 4C
You should take care when reading this data in a system using the big-endian representation of data, but if you are the only one using your application, or you can be certain that it will only be used on a little-endian system, you don't need to worry about it.
P.S.: This can also be a problem if you need to take the last two bytes of an integer (for example) while working in assembly, where you need to know exactly how the machine represents the data.
Upvotes: 0
Reputation: 3733
This is called byte order, and you should read the wikipedia web page about it (and perhaps about computer architecture more generally) to understand it in more detail. Meanwhile, if you want to emit specific byte pattterns to represent particular data, use an array of unsigned char. You can't portably use fwrite
to write structures, arrays or primitive types to a disk file (at least, you can't expect any particular output pattern) except in the case of unsigned char.
Upvotes: 0
Reputation: 43472
This is because your computer uses little endian storage semantics. This means that the little end of a number comes first. You're used to seeing numbers where the big end comes first (e.g. 340,000
, where the thousands column comes before the tens column.)
If your data will never be read on a big endian system such as an old PowerPC Mac, then you can write your numbers out this way, them read them back in on the same system, and you'll get them correctly ordered.
If you expect this data to be shared across systems that use different endiannesses, you must pick a byte order, stick with it, and perform conversion to/from that byte order when writing to a file. (Since you're not aware of the concept of endianness, I suspect this will not come into play for you.)
Upvotes: 4
Reputation: 504
look into little- and big-endian numbers. Integers stored 'Big-endian' are stored with the most sigificant bit (of the integer) first, those stored 'Little-endian' are stored least significant bit first.
Try http://en.wikipedia.org/wiki/Endianness - Not that I'd rely on Wikipedia for a technical article, but it puts it simply.
Upvotes: 0