Написание и чтение (fwrite – fread) структуры с указателями

Я работаю над проектом почтового ящика, и у меня есть две структуры:

struct mmbox_mail

struct mmbox_mail { char *sender, *recipient; char *obj, *date; char flags; size_t size; }; 

а также

mail_t

 typedef struct{ struct mmbox_mail info; void *body; void *next; } mail_t; 

Я не могу изменять поля структур, потому что мне нужны переменные данные (для этого я использовал char * вместо char []).

Каждая структура mail_t – это почта. Мне нужно сохранить каждую почту пользователя в файле, который может быть двоичным или текстовым файлом (но я думаю, что это лучше с двоичным файлом, потому что у меня есть тело void* , которое трудно сохранить в виде обычного текста.

Я пытался это сделать, но похоже, что он не работает:

 while(mailtmp != NULL){ fwrite(mailtmp, sizeof(mail_t), 1, fp); /* next mail */ mailtmp=mailtmp->next; } 
 while(mailtmp != NULL){ /* i have a list of mails and i use a mailtmp pointer to save each mail */ 

Не могли бы вы помочь мне? Я пытался найти везде, но я не нашел человека, который попросил сохранить две структуры, одну внутри.

Конечно, это не сработает, так как для строк он скопирует размер указателя (обычно 4 байта). Я вижу 3 варианта:

  1. Сериализация данных, двоичный файл (http://en.wikipedia.org/wiki/Serialization).
  2. Создание формата для хранения данных в текстовом файле.
  3. Используйте язык разметки, такой как XML / JSON и т. Д.

В любом случае вам нужно будет пройти через каждое поле структуры, чтобы записать его в файл данных. Что касается чтения, то в первых двух случаях вам нужно будет делать чтение точно в том порядке, в котором вы написали данные, в третьем случае вы сможете читать поля независимо в любом порядке.

Если вы выберете первый метод, для каждого поля строки (char *) напишите также байт с нулевым завершением, чтобы вы всегда знали, где он заканчивается при чтении.

То, что вы делаете, это сохранение буквального двоичного представления mail_t в текстовый файл, который представляет собой всего лишь несколько указателей. Что вы хотите сделать, это что-то вроде:

 fprintf( fp, "To: %s\nFrom: %s\n....\nContents: %*s\n\n", mailtmp->info.recipient, mailtmp->info.sender, mailtmp->info.size, mailtmp->body ); 

Это отобразит значения, указанные в виде строки, и сохранит их в файле. Указатель на место в памяти, хранящееся в вашем приложении, немного бесполезен большинству людей после закрытия приложения;)

EDIT: «Не могли бы вы мне помочь? Я пытался искать везде, но я никогда не нашел кого-то, кто попросил бы сохранить две структуры, одну внутри друг друга».

Если у вас были только типы данных первого classа, такие как int или float и т. Д., Ваш метод работал бы отлично. Однако, поскольку вы используете типы второго classа, а именно ваши char и void массивы, вы должны фактически указать, как должны указываться указанные данные.

ну, вы сохраняете указатель структуры в файл. Не указывайте данные, на которые он указывает. Даже если вы храните структуру, которую вы хотите, ее трудно получить из файла. Я думаю, вам нужен компонент сериализации, такой как google protocal buffer . то вы можете написать адаптер, перевести struct на объект probuf, а затем сохранить его в файл. Когда вы захотите, отыщите it.hoping, это поможет вам 🙂

Давайте будем гением компьютера.