Вы не хотите использовать long int. Это может быть разных размеров на разных платформах, так что это не стартер для независимого от платформы формата. Вы должны решить, какой диапазон значений должен быть сохранен в файле. 32 бита, вероятно, проще всего.
Вы говорите, что не беспокоитесь о других платформах пока . Я буду считать, что это означает, что вы хотите сохранить возможность их поддержки, и в этом случае вы должны определить порядок байтов вашего формата файла. x86 имеет младший порядок, так что вы можете подумать, что это лучше. Но big-endian - это «стандартный» порядок обмена, если он есть, поскольку он используется в сети.
Если вы идете для big-endian («порядок сетевых байтов»):
// can't be bothered to support really crazy platforms: it is in
// any case difficult even to exchange files with 9-bit machines,
// so we'll cross that bridge if we come to it.
assert(CHAR_BIT == 8);
assert(sizeof(uint32_t) == 4);
{
// write value
uint32_t value = 23;
const uint32_t networkOrderValue = htonl(value);
fwrite(&networkOrderValue, sizeof(uint32_t), 1, file);
}
{
// read value
uint32_t networkOrderValue;
fread(&networkOrderValue, sizeof(uint32_t), 1, file);
uint32_t value = ntohl(networkOrderValue);
}
На самом деле вам даже не нужно объявлять две переменные, просто немного сбивает с толку, заменяя «значение» его сетевым эквивалентом в той же переменной.
Это работает, потому что «сетевой порядок байтов» определен так, чтобы любая последовательность битов приводила к взаимозаменяемому (старшему) порядку в памяти. Нет необходимости связываться с объединениями, потому что любой сохраненный объект в C может рассматриваться как последовательность символов. Нет необходимости в специальном случае для порядка байтов, потому что это то, для чего нужны ntohl / htonl.
Если это слишком медленно, вы можете начать думать о чёртово оптимизированной подстановке байтов для конкретной платформы, с SIMD или чем-то ещё. Или используя little-endian, исходя из предположения, что большинство ваших платформ будут с прямым порядком байтов, и поэтому они быстрее «в среднем» по ним. В этом случае вам нужно написать или найти функции «от хоста до байтов» и «от байтов до хоста», которые, конечно, в x86 просто ничего не делают.