Is there any way to force fwrite() to write in big-endian format no matter what? I am trying to write a MIDI file and they are always big-endian. Converting every value I write to big endian beforehand would be extremely tedious. Ideas?

Recommended Answers

All 8 Replies

write a wrapper function such as mywrite() and call it instead of fwrite().

How tedious it is depends on how many different types you need to reverse. If just ints:

typedef unsigned char uchar;

union IntBytes {
    int i;
    uchar b[sizeof(int)];
};

WriteInt( int n, FILE* fout ) {
    union IntBytes uBytes;
    int i;
    uBytes.i = n;
    for (i = sizeof(int) - 1; i >= 0; --i)
        fputc( uBytes.b[i], fout );
}

Would that solution be more or less efficient than calling a function like this on the data before writing:

void swapEndianL(unsigned int *x)
{
	*x = (*x>>24) |
	 ((*x << 8) & 0x00FF0000) |
	 ((*x >> 8) & 0x0000FF00) |
	 (*x << 24);
}

You should profile them. Post your results.

Well this isn't a terribly performance-intensive part of my program, and I have to submit the whole bloody thing by friday, so maybe i'll get to it another time, and post the results if anyone is still intersted.

Don't bother. Mine was "conceptually simple." Your bit-shifting solution is best. It's even a perfect candidate for coding in assembly if performance was an issue.

If you don't mind including <arpa/inet.h>, you can use the htonl() function:

int newval = htonl(origval);

The "h" on the front is for "host" and the "n" is for network, "l" on the end for "long" (there is also a version for 16-bit integers). Hence, "Host to network Long". Network format is big endian.

On platforms that are already big endian (like Solaris), it's defined as a NULL macro.

Is there any way to force fwrite() to write in big-endian format no matter what? I am trying to write a MIDI file and they are always big-endian. Converting every value I write to big endian beforehand would be extremely tedious. Ideas?

It would be a better idea to keep you code more portable to hanlde big endian/little endian environments. In either case, create a small library or API of functions that you can call before you execute IO. For example, you might have some custom functions that wrap the socket htons/l or ntohs/l functions and opearate on the stream or array or pointer/length you pass. Use that approach and YOU guarantee the format of the data you write to the disk, network, or other file system. You can also add encryption in this manner as well. Good luck

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.