Здравствуйте, IT, Вы писали:
IT>Всё зависит от многих вещей, как всегда
Это точно! Несмотря на то, что топику уже несколько лет, я хотел бы вставить свои 5 копеек в обсуждаемую тему, тем более, что эта тема находится в статьях сайта, а значит не имеет срока давности.

Наиболее правильным и переносимым (но медленным) будет вообще не сохранять в файл структуру целиком. Более того, не желательно даже int записывать в файл напрямую. Одна из причин уже была озвучена в топике: несовпадающие размеры int в разных компиляторах даже на одной платформе. Другая причина кроется в переносимости. Не факт, что ваша программа (или даже её отдельный модуль) никогда не переедут под UNIX. В отличие от Windows, UNIX существует на большом зоопарке платформ. Некоторые из них имеют big-endian представления чисел (первым идёт старший байт). Если на такой платформе сохранить int в файл как есть, а затем прочитать этот файл на Intel-платформе, то мы получим совершенно другое число. Например (пусть размер int будет 32 бита), если на big-endian сохранили 0x12345678, то в little-endian прочитаем 0x78563412.
Для большинства эти детали не существенны, так как не так уж и много программистов (надо признаться, и я в том числе) пишут сразу для нескольких платформ. Но, по крайней мере, задуматься о потенциальных проблемах переносимости надо.
Как же сохранять данные в файл, чтобы и файл, и программа его читающая были переносимы? Ответ уже был в этом топике: сохранять всё в xml или другом текстовом файле. Однако, если объём данных велик, и от двоичных данных никуда не деться, то сохранять все данные следует побайтно. Пример сохранения 32-битного int (предполагаем, что система, где char имеет размер, не равный 8 бит, нам не попадётся):
#include <stdio.h>
const char filename[] = "file.dat";
void read_int(FILE* f, int* d)
{
unsigned char buf[4];
unsigned char* p = buf;
fread(buf, sizeof(buf), 1, f); // portable
*d = *p++;
*d += *p++ << 8;
*d += *p++ << 16;
*d += *p++ << 24;
// fread(d, sizeof(*d), 1, f); // not portable
} // read_int
void write_int(FILE* f, int d)
{
unsigned char buf[4];
unsigned char* p = buf;
*p++ = d & 0xff;
*p++ = (d >> 8) & 0xff;
*p++ = (d >> 16) & 0xff;
*p = (d >> 24) & 0xff;
fwrite(buf, sizeof(buf), 1, f); // portable
// fwrite(&d, sizeof(d), 1, f); // not portable
} // write_in
void help()
{
fprintf(stderr, "Usage: fileio {w|r}\n");
exit(1);
} // help()
int main(int argc, char *argv[])
{
const int data = 0x12345678;
FILE* fi;
FILE* fo;
int tmp;
char err_msg[255];
if (argc != 2) help();
if (! strcmp(argv[1], "w")) {
fo = fopen(filename, "w");
if (! fo) {
sprintf(err_msg, "Can not open file '%s'", filename);
perror(err_msg);
exit(1);
}
write_int(fo, data);
fclose(fo);
}
else if (! strcmp(argv[1], "r")) {
fo = fopen(filename, "r");
if (! fo) {
sprintf(err_msg, "Can not open file '%s'", filename);
perror(err_msg);
exit(1);
}
read_int(fo, &tmp);
fclose(fo);
printf("Readed %#08x. Must be %#08x\n", tmp, data);
}
else
help();
return 0;
} // main()
Если гложут вопросы быстродействия, особенно в свете того, что big-endian систем не много и ради этой редкости мы замедляем считывание файлов, то необходимо ввести условную компиляцию: на little-endian системе читать int целиком, на big-endian – побайтно. Опять же, нельзя забывать про отличия размера int на разных платформах.
Хочу отметить, что я далеко не гуру в этом вопросе, и все мои замечания основаны лишь на изучении и портировании Open source ПО на компьютер RM200 (RISC-процессор R4000 (big-endian), ОС SINIX).