Question subject: Ensuring integer are written as 32 bits
Posted: Sat Nov 08, 2008 1:28 am
Joined: Sun Oct 19, 2008 3:47 pm Posts: 281 Has thanked: 0 time Have thanks: 1 time
I have a program that writes a binary config file for another piece of hardware. One of the requirements of the file is that integer values are 32 bits. Currently the file is created as expected when run on a 32 bit machine. However, I need to make it portable, so that it could also be run on a machine that uses 64 bit ints, and I'm not sure how to do it.
Currently, the code is something like this:
Code:
struct Data { int nInt1; int nInt2; char czString[32]; };
...
Code:
FILE* pFile = fopen("filename.bin", "wb"); Data data; // do stuff
fwrite(&data, sizeof(data), 1, pFile);
...
Now, I know this is not portable because of int size (as well as possible packing issues) so I thought about changing it to something like this:
Code:
const int INT_SIZE = 4; const int STRING_LENGTH = 32; struct Data { int nInt1; int nInt2; char czString[STRING_LENGTH]; };
...
FILE* pFile = fopen("filename.bin", "wb"); Data data; // do stuff
Will this actually work? Will this write the lower 32 bits of an int if it is 64 bits? If not, how can I guarantee it will write the lower 32 bits?
AnswerBot
Question subject: Re: Ensuring integer are written as 32 bits
Posted: Sat Nov 08, 2008 1:35 am
Joined: Sun Oct 19, 2008 3:53 pm Posts: 229 Has thanked: 0 time Have thanks: 0 time
A 32-bit integer can be represented as an array of 4 chars, assuming 8 bits per byte. Conversion between ordinary integers and this array can be done by bitwise mask-and-shift operations. The following should work for any unsigned integer type >= 32 bits; I've used long long here:
Code:
#include <stdio.h> #include <limits.h>
int main(void) { unsigned long long i = 1234567890; unsigned char c[4];
printf("Your integers are %i bits\n", CHAR_BIT * sizeof(i));
c[0] = i & 0xff; /* least significant byte */ c[1] = (i & 0xff00) >> 8; c[2] = (i & 0xff0000) >> 16; c[3] = (i & 0xff000000) >> 24;
Your integers are 64 bits 0x499602d2 == 0x499602d2
The first hex value is derived from i, the second from c[], and they should be the same. I don't have a 64-bit machine to try this on; maybe someone who has would oblige!
(To write binary data from c[] you'd need a different format string of course.)
There are also considerations of endianess to be taken into account.