0

For a class assignment I have an array that I need to define in main() but allocate memory and load the data in a sperate function load(). Right now autos[] doesn't get populated with the data from the file. Any help is appreciated.

The struct has 4 fields: name, floatNum, intNum, color, that the data needs to be written to. size and autos[] are both defined in main and size refers to the number of elements in autos[].

Load function

void load(int size, struct data autos[]) {
    
    autos = malloc(size * sizeof(struct data));
   
    FILE *data;
    data = fopen("./hw3.data", "r");
    int i;
    for (i = 0; i < size; i++) {
        fscanf(data, "%s %f %d %s", autos[i].name, &autos[i].floatNum, &autos[i].intNum, autos[i].color);
    }
}
8
  • 1
    If you pass the array into the function, the allocation problem is for the calling code, not the function shown. If you want to allocate the array in the function, it is usually best to return the pointer to the allocated data, either directly as the return value or via a pointer to pointer argument that you assign to. That means either struct data *load(int size); or int load(int size, struct data **p_autos) where your calling code has struct data *autos; and you pass &autos to the function. If the memory allocation fails (or the file open fails), you should return a null pointer. Commented Sep 16, 2022 at 16:35
  • Do you mean something like this? (Sorry for the awful formating) void load(int size, struct data (*autos)) { *autos = (struct data)malloc(size * sizeof(struct data)); FILE* data; data = fopen("./hw3.data", "r"); int i; for (i = 0; i < size; i++) { fscanf(data, "%s %f %d %s", autos[i]->name, &autos[i]->floatNum, &autos[i]->intNum, autos[i]->color); } } Commented Sep 16, 2022 at 17:24
  • No. I used struct autos **p_autos and it seems that you're using struct autos (*autos) — there's a major difference (and the relevant difference isn't the redundant parentheses)! But maybe the problem is SO's use of MarkDown. Use back quotes around code fragments in comments to avoid * being interpreted as formatting — start/stop italic/bold etc. So, type `void load(int size, struct data *(*autos)) …` to get the code formatted better, if that's what you meant. Commented Sep 16, 2022 at 17:43
  • You certainly want to check that fopen succeeds and that each call to fscanf returns 4. You also want to limit the scans with eg fscanf(data, "%31s %f %d %31s" ...) (assuming the size of each field is not less than 32). You may also want a width modifier on the %f and %d to avoid undefined behavior for inputs that overflow the type, but that's probably overkill at this point. Checking the values returned by fopen and fscanf is essential, however. Commented Sep 16, 2022 at 17:50
  • I just did an answer: Creation of Dynamic Array of Strings in C that shows how to have a dynamic array struct and I used it to allocate an array of structs that was populated by reading in the struct data from a file. Commented Sep 16, 2022 at 18:27

1 Answer 1

0

I figured it out. Thank you Craig and Johnathan for giving me some pointers. It takes the size of the array needed (from a different function) and creates one and scans through the data file putting data into each element.

struct data* load(int size){
    
    struct data* autos = malloc(size * sizeof(struct data));  

    FILE* data;
    data = fopen("./hw3.data", "r");

    int i = 0;
    for (i = 0; i < size; i++) {
        fscanf(data, "%20s %f %d %20s", autos[i].name, &autos[i].floatNum, &autos[i].intNum, autos[i].color);
    }

    fclose(data);

    return autos;
}
Sign up to request clarification or add additional context in comments.

Comments

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.