Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading and writing a malloc'd linked list from/to a binary file

I need to do an assignment for a class I'm taking. It's a simple phonebook app in C, and i'm having a little trouble with it since I need to use some new stuff in the program and the deadline is pretty tight.

I looked around and found some answers, but a new one came up every time. :)

This is my (simplified) program:

typedef struct record
{
    char fname[31];
    char lname[31];
    char tel[21];
    struct record *next;
} record;


record *new_entry(record *first, char *fname, char *lname, char *tel)
{
    record *new;
    new=(record*) malloc(sizeof(record));
    strcpy(new->fname, fname);
    strcpy(new->lname, lname);
    strcpy(new->tel, tel);
    new->next=first;
}


void fileopen (char *db_file)
{
    FILE *fp;  

    fp=fopen(db_file, "rb");
    if (fp==NULL) 
    {
        fp=fopen(db_file, "wb");
        fclose(fp);
        fp=fopen(db_file, "r+b");
    }
}



int main
{
 char db[51];
 record *next = NULL;

 printf("File:           "); scanf("%s, db);
 fileopen(db);
 printf("First name:     "); scanf("%s", fname);
 printf("Last name:      "); scanf("%s", lname);
 printf("Phone number:   "); scanf("%s", tel);
 first=new_entry(*first, fname, lname, tel);
}

I left out the unessential parts. Now I know it's not much, but my class leader said I should use binary files to store and restore the data. But I got really confused if how am I supposed to use fread and fwrite.


Thanks so much for the solution! I think I start to understand the concept. The program now stores the data (At least I think it does, because the file keeps growing as I add more data.) When starting a fresh binary file, the program correctly displays the data when requested, but if I close it, and reopen the same file, nothing happens when it tries to list the contacts.

Here's the (simplified again, i have 10 details in one record in the actual assignment) open function:

record *open (char *db_file, record start)
{
  FILE *fp
  record *temp = start;
  fp=fopen(db_file, "rb");
  while (fread(temp, sizeof(rekord), 1, fp)>0) 
    {
        fread(temp->fname, sizeof temp->fname, 1, fp);
        fread(temp->lname, sizeof temp->lname, 1, fp);
        fread(temp->tel, sizeof temp->tel, 1, fp);
    temp=temp->next;
    }
  fclose(fp);
  return temp;
}

And in main(), I use:

start=open(db, start);

The declaration part:

record *start=NULL;

Thanks again if someone replies.

like image 247
nycht Avatar asked Nov 11 '12 10:11

nycht


2 Answers

To write your linked list to a file, you can run through the list, and write your structure.

#include <stdio.h>

record *it = first;

while (it != NULL) {
    fwrite (it->fname, sizeof it->name, 1, stream);
    fwrite (it->lname, sizeof it->lname, 1, stream);
    fwrite (it->tel, sizeof it->tel, 1, stream);
    it = it->next;
}

stream is a file you can open with wb mode in fopen.

like image 118
md5 Avatar answered Nov 15 '22 08:11

md5


So, hopefully this assignment will drive home why manually serializing/deserializing is a terrible idea (in the industry, the real way to do this sort of thing is by automatic code generation such as protocol buffers), but for the purposes of this assignment, you will need to write the contents of the linked list without writing the links, and then you will need to reconstruct the links when you deserialize, since it would be incorrect to simply write and read the addresses of the next pointers that were in the list.

like image 31
Michael Aaron Safyan Avatar answered Nov 15 '22 08:11

Michael Aaron Safyan