fwrite an integer depends on endianness, but is there a way to write an integer 0x00000004 to a file such that it can be fread always as 0x00000004 regardless of machine it's run on.
One thought is to write the first bit, then second, then third always in a specific order,such as grabbing each decimal value using modulus or bit shifting.
Not sure if there's a way to force fwrite to write as little endian without having some convoluted check to see if the current system is big endian, and then reversing the bits before fwriting.
Another thought is to store it in the file as ascii, which isn't a huge deal it just turns 4 bytes into maybe 8 (hex). But I figure this is just a lazy solution.
I want to fwrite and fread from possibly different machines, so both operations need to be able to fwrite and fread the same endianness, and I'm not sure (after searching this site) on a portable way to do this (without using some obscure library that may or may not be on certain machines).
I don't think you need to worry about bit-level endianness, I think they are always the same how is data stored at bit level according to "Endianness"?
I would probably use a fixed endiannes to store the data, and make some wrapper functions for fread and fwrite.
So say you decide to store everything in little endian, the wrappers would check the machine endianness and:
EDIT E.g., your fwrite could look like this (not tested though, just to illustrate the idea). Endianness check from C program to check little vs. big endian:
size_t lendian_fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream)
{
if (size != 4)
{
/* Warn and exit */
}
int x = 1;
if ( *((char*)&x) == 1)
{
/* Little endian machine, use fwrite directly */
return fwrite(ptr, size, nmemb, stream);
}
else
{
/* Big endian machine, pre-process first */
unsigned char *buffer = (unsigned char*) ptr;
for (int i=0; i<nmemb; i++)
{
unsigned char a = buffer[4*i];
unsigned char b = buffer[4*i + 1];
buffer[4*i] = buffer[4*i + 3];
buffer[4*i + 1] = buffer[4*i + 2];
buffer[4*i + 2] = b;
buffer[4*i + 3] = a;
}
return fwrite(ptr, size, nmemb, stream);
}
}
I just made this simple endian swap fwrite. Works with any endianness, use it whenever you want the byte order swapped. Works for every element size and does not change the original data:
size_t endian_swap_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
{
unsigned char *buffer_src = (unsigned char*)ptr;
unsigned char *buffer_dst = new unsigned char[size*nmemb];
for (size_t i = 0; i < nmemb; i++)
{
for (size_t ix = 0; ix < size; ix++) {
buffer_dst[size * i + (size - 1 - ix)] = buffer_src[size * i + ix];
}
}
size_t result = fwrite(buffer_dst, size, nmemb, stream);
delete buffer_dst;
return result;
}
User contributions licensed under CC BY-SA 3.0