user1466609
user1466609

Reputation:

Why the byte are upside down?

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 F1etc, 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

Answers (5)

Thomas Padron-McCarthy
Thomas Padron-McCarthy

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

Alin Huruba
Alin Huruba

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

James Youngman
James Youngman

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

Jonathan Grynspan
Jonathan Grynspan

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

Joe Bowman
Joe Bowman

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

Related Questions