0

I wrote a C code to implement a dictionary using linked-list(nodes are in sorted order) I want to save the data to a file and be able to reload the data when I run the program next time. I'm having trouble loading the data from file. Here is my code for reading and writing data:

struct node{
    char word[20];
    char meaning[5][100]; //2D array for saving multiple meanings of a word
    struct node *next;
};

void ReadData(struct node *head)
{
    struct node *tail;
    FILE *fp = fopen("dictionary.data", "rb");
    if(fp == NULL)
    {
        printf("Error opening file..\n");
        return;
    }
    while(!feof(fp))
    {
        tail = (struct node*)calloc(1, sizeof(struct node));
        fread(tail->word, sizeof(head->word), 1, fp);
        fread(tail->meaning, sizeof(head->meaning), 1, fp);
        if(head == NULL) //for fresh run head is initialized with NULL
        {
            tail->next = head;
            head = tail;
        }
        else
        {
            head->next = tail;
            head = head->next;
        }
    }
    fclose(fp);
}

I can't load data from the file to the linked list. Code is not working. I can't figure out where the problem is..
Here's how I'm writing the data to the file :

/*I think this code is working because size of the file increases after running the code*/
void WriteData(struct node *head)
{
    FILE *fp = fopen("dictionary.data", "wb");
    if(fp == NULL)
    {
        printf("Error opening file..\n");
        return;
    }
    while(head != NULL)
    {
        fwrite(head->word, sizeof(head->word), 1, fp);
        fwrite(head->meaning, sizeof(head->meaning), 1, fp);
        head = head->next;
    }
    fclose(fp);
}

I've used sizeof, instead of strlen, it's a string. It'll have null character at the end - no problem with string. It'll consume more memory though.

16
  • that one is not for reading.. It's for writing the data to the next node. Reading will be done by fread Commented May 30, 2017 at 15:52
  • in ReadData reading is done by fread if-else part is for fixing the links between the nodes Commented May 30, 2017 at 15:55
  • in else part head->next = tail assigns the address of new node to the next file of the node pointed by head. Now we have to point the head to the new node(tail), address of the new node is assigned to the next filed of the previous node(head->next = tail). So in order to point the head to the new node I used head = head->next as head->next=address of tail Commented May 30, 2017 at 16:07
  • ok.. But I think it's the same thing. coz head->next holds the address of tail Commented May 30, 2017 at 16:09
  • 1
    The main problem is that you can not change caller 's head in the function. In ReadData, no argument is necessary. head should be returned. Commented May 30, 2017 at 16:18

1 Answer 1

2

try this (untested):

void ReadData(struct node **head){//or struct node *ReadData(void){ ... return head; }
    struct node temp = { .next = NULL };//{ {0}, {{0}}, NULL}
    struct node *hp, *curr;
    FILE *fp = fopen("dictionary.data", "rb");

    if(fp == NULL){
        printf("Error opening file..\n");
        return;
    }

    hp = *head;
    while(fread(temp.word, sizeof(temp.word), 1, fp) && fread(temp.meaning, sizeof(temp.meaning), 1, fp)){
        struct node *np = malloc(sizeof(*np));
        if(np == NULL){
            perror("couldn't make new node by malloc:");
            return ;//release list
        }
        *np = temp;

        if(hp == NULL){//for fresh run head is initialized with NULL
            curr = hp = np;
        } else {//If *head isn't NULL, you need to move to the last node first.
            curr = curr->next = np;
        }
    }
    fclose(fp);
    *head = hp;
}
//....................
int main(void){
    //...
    struct node *head = NULL;
    //...
    ReadData(&head);
    //...
Sign up to request clarification or add additional context in comments.

2 Comments

a void function cannot be returning NULL. and if malloc() fails, then must pass all pointers to free(), otherwise there is a massive memory leak.
@user3629249 Yes, it was my mistake that Null's return was. Thank you for pointing out. I just pointed out the release of the list when Malloc failed, as it is not central as an example.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.