2

I have to build a function that reads backer and reward information (structs) from files. If the files do not exist, notify the user, create new files and display the main menu. Once a file is open, data is read into an array of structs by dynamically allocating sufficient memory for each entry read from the file. Here is how far I have gotten. I'm not sure how to approach the array of structs or to allocate the memory correctly. It's a topic I'm not that strong on.

struct backer_info {
    int backer_ID;
    char *backer_name[40];
    char *email[40];
    char *country[20];
}backer;

struct reward_info {
    int reward_number;
    int backer_ID;
    float price;
    int num_drones;
    int priority;
}reward; 

void load_data(){

    int i;
    int j;
    FILE *backers;
    FILE *rewards;

    struct backer_info backer = {0, "", "", ""};

    if ((backers = fopen("backers.txt", "rb")) == NULL) {
        printf("File not found \n New  backers file created \n");
    }
    else{

        for (i = 1; i <= !feof; i++) {

             malloc(sizeof(sizeof(struct backer_info)));

             fread(&backer, sizeof(struct backer_info), 1, backers);

        }
        fclose(backers);
    }


    struct reward_info reward = {0, 0, 0, 0, 0};

    if ((rewards = fopen("rewards.txt", "rb")) == NULL) {
        printf("File not found \n, New rewards file created \n");
    }
    else{
        for (j = 1; j <= !feof; j++) {

            malloc(sizeof(struct reward_info));

            fread(&reward, sizeof(struct reward_info), 1, rewards);
        }
        fclose(rewards);
    }
    /* Use the allocated space */
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
jeff88
  • 21
  • 4
  • 1
    You have a lot of problems. You need to assign the result of `malloc()` to some appropriate variable; as it stands, you leak memory. You don't want the nested `sizeof(sizeof(struct backer_info))` notation; that's the same as `sizeof(size_t)` (and also `sizeof(sizeof(char [100000000]))`). You need to test the return value from `fread()`; it tells you whether your read anything. You can't spot EOF until after an I/O function has spotted it. You don't use `feof()` as shown (see [`while (!feof(file))` is always wrong](http://stackoverflow.com/questions/5431941)!). – Jonathan Leffler Dec 13 '15 at 17:32
  • 1
    In the definition of struct backer_info, you almost certainly do not want arrays of char pointers, instead you want arrays of chars. As in, `char *backer_name[40]` is defining an array of char pointers. Get rid of the `*` before `backer_name`, `email`, and `country`. – Duane McCully Dec 14 '15 at 03:39

2 Answers2

1

For loading your file into an array of struct backers, something in the pattern of:

int i;
FILE *backers;
struct backer *backer_array = NULL;
size_t backer_size = 0;
size_t bytes_read;

if ((backers = fopen("backers.txt", "rb")) == NULL) {
    printf("File not found \n New  backers file created \n");
}
else{
    /* Get the file size. */
    fseek(backers, 0 , SEEK_END);
    backer_size = ftell(backers);
    rewind(backers);

    /* Make sure that file size is an integral number of records. */
    backer_size = backer_size - (backer_size % sizeof(struct backer));

    /* Allocate space. */
    if (backer_size > 0) {
        backer_array = malloc(backer_size);
    }

    /* Read the entire file in one read. */
    if (backer_array) {
        bytes_read = fread (backer_array, 1, backer_size, backers);
        /* backer_size will now represent the number of elements in the array. */
        backer_size = backer_size / sizeof(struct backer);
    }

    /* Close the file. */
    fclose(backers);
}

if (backer_array) {
    for (i = 0; i < backer_size; i++) {
      /* Do stuff with backer_array[i]; */
    }
    free(backer_array); 
}
Duane McCully
  • 406
  • 3
  • 6
1

Here is a better code. The instance of the structures backer and reward are as pointers:

struct backer_info {
    int backer_ID;
    char *backer_name[40];
    char *email[40];
    char *country[20];
} backer;

struct reward_info {
    int reward_number;
    int backer_ID;
    float price;
    int num_drones;
    int priority;
} reward; 

void load_data(){

    int i;
    int j;
    FILE *backers;
    FILE *rewards;

    struct backer_info *backer;

    if ((backers = fopen("backers.txt", "rb")) == NULL) {
        printf("File not found \n New  backers file created \n");
    }
    else{
        if (backer = malloc(sizeof(struct backer_info)) == NULL) {
             printf("Memory could't be allocated\n");
        for (i = 1; !feof(backers); i++) {
             fread(&backer, sizeof(struct backer_info), 1, backers);
             backer = realloc(backer, (i + 1) * sizeof(struct backer_info));
        }
        fclose(backers);
    }


    struct reward_info *reward;

    if ((rewards = fopen("rewards.txt", "rb")) == NULL) {
        printf("File not found \n, New rewards file created \n");
    }
    else{
        if (reward = malloc(sizeof(struct reward_info)) == NULL) {
             printf("Memory could't be allocated\n");
        }
        for (j = 1; !feof(rewards); j++) {
            fread(reward, sizeof(struct reward_info), 1, rewards);
            reward = realloc(reward, (i + 1) * sizeof(struct reward_info));
        }
        fclose(rewards);
    }
    /* Use the allocated space */
}
John
  • 1,012
  • 14
  • 22