The way I would approach this problem is by writing a binary file with the following structure:
begin file header:
0x00 :: 0x03 [ 4 bytes] number of entries
for each entry n at offset 0x04 + n * 4:
0x00 :: 0x03 [ 4 bytes] string length of entry (including terminating \0)
end file header
after the header, write all entries as strings to the file, including the terminating \0
byte.
To read this file, I would use fopen
, fread
, fclose
to read the array of offsets from the file, and then I would mmap
the file, and transform the array of offsets to an array of pointers into the mmapped region.
Portability Note:
If you want to be able to read the file on one architecture and read it on a different one, you will need to
- make sure you use fixed width datatypes (e.g.
uint32_t
, uint64_t
)
- decide on a byte order to avoid endianness issues.
so, say, if you wanted to write a uint32_t
to a file, without endianness issues you could use
void
write_uint32 (FILE *f, uint32_t v)
{
unsigned char out[4] = { 0 };
out[0] = v & 0xff; v >>= 8;
out[1] = v & 0xff; v >>= 8;
out[2] = v & 0xff; v >>= 8;
out[3] = v
fwrite(out, 1, sizeof(out), f);
}
and to read the same value
uint32_t
read_uint32 (FILE *f)
{
unsigned char in[4] = { 0 }
fread(in, 1, sizeof(in), f);
return in[3] << 24 | in[2] << 16 | in[1] << 8 | in[0];
}