Lucas Azevedo
Lucas Azevedo

Reputation: 2370

Can't point to struct being read from file in C

I'm trying to load some member structs I've saved to my Memberships.txt binary file. I can read the content into tmp without a problem, as the prints give me the correct information. The problem seems to be on the tail.next = &tmp; line.

The idea is to keep head as a pointer so I can pass it to the other functions I'll use later on. tail should initialize with the member head points to and will only be used to modify the .next field on it, so I add the members being read at the end of the list.

Can anyone help me?

FILE* f = fopen("Memberships.txt", "rb");
member* head = malloc(sizeof(member));
member tail = *head;
member tmp;
while(fread(&tmp, sizeof(struct member), 1, f) == 1){
  printf("Read member %d from file.\n", tmp.number);
  printf("Name: %s\n", tmp.first_name);
  printf("Surname: %s\n", tmp.second_name);
  tail.next = &tmp;
  tail = tmp;
}
tail.next = NULL;
printf("Loaded %d members into list!\n\n",tail.number);
if(head->next == NULL){
  printf("%d",666);
}

Outputs:

Read member 1 from file.
Name: Lucas
Surname: Azeve
Read member 2 from file.
Name: Mark
Surname: Lala
Loaded 2 members into list!

666

I've implemented the changes that @anonmess suggested like:

member* head = malloc(sizeof(member));
member tail = *head;
member tmp;
while(fread(&tmp, sizeof(struct member), 1, f) == 1){
    member* read = malloc(sizeof(member));
    strcpy(read->first_name,tmp.first_name);
    strcpy(read->second_name,tmp.second_name);
    strcpy(read->address,tmp.address);
    strcpy(read->email,tmp.email);
    read->number = tmp.number;
    read->annual_fee = tmp.annual_fee;
    read->status = tmp.status;
    read->handicap = tmp.handicap;
    read->bracket = tmp.bracket;
    read->freq = tmp.freq;
    read->rest = tmp.rest;
    read->rate = tmp.rate;
    printf("Read member %s from file.\n", read->first_name);
    printf("Name: %s\n", read->first_name);
    printf("Surname: %s\n", read->second_name);
    tail.next = read;
    tail = *read;
}

Obtaining the same results, the problem is on the last two lines. head->next is still NULL.

Upvotes: 0

Views: 355

Answers (1)

user3657941
user3657941

Reputation:

This is a stand-alone example you can modify to solve your problem:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define NAME_LENGTH 20

typedef struct _member {
    struct _member *next;
    int number;
    char first_name[NAME_LENGTH];
    char second_name[NAME_LENGTH];
} member;

member member_list[] = {
        { NULL, 1, "Lucas", "Azeve" },
        { NULL, 2, "Mark",  "Lala"  }
};

void create_file(void) {
    FILE *f = fopen("Memberships.txt", "wb");
    fwrite(member_list, sizeof(member_list), 1, f);
    fclose(f);
}

int main(void)
{
    create_file();
    FILE* f = fopen("Memberships.txt", "rb");
    if (f == NULL) {
        perror("Could not open file");
        exit(errno);
    }
    member *head = malloc(sizeof(member));
    member *tail = head;
    while (1) {
        int result;
        member *new = malloc(sizeof(member));
        result = fread(new, sizeof(*new), 1, f);
        if (1 != result) {
            if (feof(f)) {
                break;
            }
            errno = ferror(f);
            perror("Could not read from file");
            exit(errno);
        }
        printf("Read member %d from file.\n", new->number);
        printf("Name: %s\n", new->first_name);
        printf("Surname: %s\n", new->second_name);
        tail->next = new;
        tail = new;
    }
    fclose(f);
    tail->next = NULL;
    printf("Loaded %d members into list!\n\n", tail->number);
    if (head->next == NULL) {
        printf("%d",666);
    }
    return 0;
}

Output

Read member 1 from file.
Name: Lucas
Surname: Azeve
Read member 2 from file.
Name: Mark
Surname: Lala
Loaded 2 members into list!

Hopefully, this will show you one way to allocate memory for each member and read the data from the file without doing any unnecessary copying. You can safely ignore the code I used to create the file. I needed some data and I always try to get the computer to do as much work as possible.

Upvotes: 1

Related Questions