Работа с различными архитектурами при загрузке данных с помощью stdio
Я хочу прочитать некоторые данные из файла. Скажем целое число:
fread(&var1, 4, 1, f);
Где var1-целое число. Но потом я подумал, что это небезопасно, так как нет никакой гарантии, что целое число имеет длину 4 байта. (Я игнорирую другие вопросы, такие как феоф и феррор, ради этого вопроса).
Я также вскоре понял, что есть еще больше проблем, чем просто размер int, таких как конечность системы, и, вероятно, другие, о которых я даже не думал от.
Итак, как лучше всего обеспечить правильную интерпретацию ваших данных, которые Вы читаете? До сих пор единственное, что я могу придумать, это просто хранить данные как текст, а не как двоичные данные, читать в тексте и преобразовывать его во время выполнения. Я бы предположил, что независимо от решения, если вы хотите убедиться, что оно портативно, оно всегда будет включать в себя какую-то форму преобразования в любом случае.
Спасибо.
2 ответа:
Чтобы избежать проблемы размера, вы должны делать:
Если вы обеспокоены тем, что размерfread(&var1, sizeof(var1), 1, f);
int
может варьироваться между платформой, которая записывает данные, и платформой, которая их читает, то у вас есть более фундаментальная проблема. В этом случае следует избегать использованияint
,short
, и т.д., и использовать типы, определенные в<stdint.h>
, такие какint16_t
,uint32_t
.Чтобы справиться с проблемами endianness, вы должны рассмотреть возможность написания вспомогательных функций, которые явно пишут / читают человека байты в известном порядке, например:
void write_uint32_t(uint8_t *buf, uint32_t x) { buf[0] = (uint8_t)(x >> 0); buf[1] = (uint8_t)(x >> 8); buf[2] = (uint8_t)(x >> 16); buf[3] = (uint8_t)(x >> 24); }
Все вышесказанное относится только к целочисленным типам. Для типов с плавающей запятой не существует идеального универсального решения.