0

I am carrying out a small project concerning the management of user data, now I have to create a procedure that must allow reading from a binary file (whose name is passed as a parameter) a list of users. Dynamic allocation must take place within the subroutine. The file must be opened and closed inside the function. The pointer to the dynamic vector must be assigned to the relevant field of the 'data' parameter as well as the number of elements read. The function prototype must have this form:void loadData(VD *data, char *namefile);

I have two functions to open and close the file:

 FILE * openFile(char *nameFile, char *mode){
    FILE *fp = fopen(nameFile, mode);

    if(fp == NULL)
        exit(-1);

    return fp;
}

FILE * closeFile(FILE * fp) {

    if (fp != NULL)
        fclose(fp);

    return NULL;

}

The implementation of the loadData function I made is this:

void loadData(VD *data, char *namefile){
    FILE* f = openFile(namefile,  "r");
    char string[200]; //I don't know what size to give to the string
    while(!feof(f)){
     fgets(string,200,f);
    }
    closeFile(f);
}

My doubts are that I don't know how to do dynamic allocation in this case, and I don't even understand what it means: "The pointer to the dynamic vector must be assigned to the relevant field of the 'data' parameter as well as the number of elements read."

Inside the txt file I have a series of people data, here is an example: https://pastebin.com/s4LxFNGE

PS This is VD:

typedef struct{
    RecordSubj *v;  //RecordSubj is a structure that contains all the data of a subject, the same ones that are present in the link I put above
    int nElements;
} VD;

This is the implementation of RecordSubj

typedef struct {
    char name[SIZE_NAME + 1];
    char surname[SIZE_SURNAME + 1];
    int height;
    float weight;
    char eyeColor[DIM_COLOR];
    char hairColor[DIM_COLOR];
    hair hairLength;
    _Bool beard;
    _Bool scar;
    char key[DIM_KEY];
    char lives[SIZE_LIVES + 1];
    GPSPosition position;
    StateOf state;
} RecordSubj;

Can you help me?

Zeld
  • 33
  • 6
  • Please show the `RecordSubj` definition. Is it a list node or not (ie does it contain a `next` or similar link pointer)? If it is the former then you can dynamically allocate one node at a time with `malloc` and link them up. If it is the latter you can `malloc` some initial array size of those structs and then use `realloc` to grow the array as needed. – kaylum Feb 09 '21 at 22:06
  • Since it is not a list node you have two choices: 1. Work out the number of elements in the file based on the file size and the struct size. Then do `data->v = malloc(num_elements * sizeof(*data->v));` 2. `malloc` an initial size and then `realloc` to grow it as needed. – kaylum Feb 09 '21 at 22:15
  • Slightly OT: Read this: https://stackoverflow.com/q/5431941/898348 – Jabberwocky Feb 09 '21 at 22:19
  • Don't put relevant information into external link but put them into the question. – Jabberwocky Feb 09 '21 at 22:20
  • @kaylum Since I also have these two functions available, what do you recommend? https://pastebin.com/8BJtnbPd – Zeld Feb 09 '21 at 22:23
  • @Jabberwocky Thanks for the advice on the while. If I put all the code here it becomes awkward to read don't you think? – Zeld Feb 09 '21 at 22:25
  • Well then you already have the second option exactly as I described. It's then a simple matter of calling `inizializeDinamicVector` at the start and then `addElement` after reading each struct from file. Not sure why you didn't provide that info from the start as it would seem clearly directly relevant. – kaylum Feb 09 '21 at 22:29
  • Tip: Spacing out your type definitions is confusing and misleading. It should be either `type* x` or `type *x`, both are understood to be pointers, but never `type * x` which implies multiplication. – tadman Feb 09 '21 at 22:40
  • I think that you will need to parse the file in the link. If you are planning into having more than one record on each file. Then you will need a parser. The data is not well-formatted for a simple program. – Bybit360 Feb 10 '21 at 01:57
  • @kaylum as Bybit360 said the problem is to parse every line to insert only the string after ':' Is there a function that allows me to select the extremes of the string that interests me? something like (':' – Zeld Feb 10 '21 at 11:02

0 Answers0