-1

i want a dynamic array of my struct Data to contais the element of the file.I don't know the dimension of the file before so i need a dynamic array to cointains it. Should i use an array of struct or do you suggest a linked list?(the purpose is to create a quick sort and sort the element of the file) Why doesn't print anything? I did something wrong with malloc e realloc?

manager.h:

#ifndef MANAGER_H
#define MANAGER_H

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

struct Data
{
    int id;
    char field1[50];
    int field2;
    float field3;
};

extern struct Data* records; 

int readFile();
#endif

managaer.c

#include "manager.h"

struct Data* records; 

int readFile(){
    FILE *file = fopen("records.csv","r");
    if(file == NULL){
        printf("Error opening file.\n");
        return 1;
    }
    records = malloc(sizeof(struct Data));
    int num=0;
    do{
        fscanf(file,"%d,%49[^,],%d,%f\n",&records[num].id,records[num].field1,&records[num].field2,&records[num].field3);
        num++;
        records = realloc(records,num*sizeof(struct Data));

    }while(num<5);

    fclose(file);

    for (int i = 0; i < num; i++)
    {
        printf("\n%d %s %d %f",records[i].id,records[i].field1,records[i].field2,records[i].field3);
    }
    
    return 0;
}
  • Is 5 the maximum number of items? In this case, why don't malloc space for 5 items from the beginning? Also, you need to initialize `num` to 0 not to 1, otherwise you write to an offset that is not reserved yet in `fscanf(file,"%d,%49[^,],%d,%f\n",&records[num] ...`, then you call `realloc` with `num + 1` elements. – David Ranieri Nov 27 '22 at 10:01
  • 5 is only a try to test the dynamic allocation. And yes, if i only do a malloc for 5 item it works, but i need to increase dynamically cause the file is much bigger – Matteo Pagliarello Nov 27 '22 at 10:05
  • Then you want `while (fscanf(...) == 4) { ... }` where 4 is the number of elements to scan instead of `do { ... } while (num < 5)` – David Ranieri Nov 27 '22 at 10:09
  • In your edit, you initilize `num` to 0 but you forget to `realloc` with `num + 1`, ok, let me write an answer ... – David Ranieri Nov 27 '22 at 10:11
  • `while (fscanf(...) == 4) { ... }` should give me the number of element in a row, in this case `num` indicate the number of row read not the element inside in a single row. – Matteo Pagliarello Nov 27 '22 at 10:12

1 Answers1

0

To read the whole file you can loop while fscanf returns the number of elements to scan, since you have 4 columns per row:

while (fscanf(file,"%d,%49[^,],%d,%f\n", ...) == 4)
{
}

You also need to take care of the value of num on each iteration, switch to:

size_t num = 0;
while (fscanf(file,"%d,%49[^,],%d,%f\n", ...) == 4) // you can avoid the "\n"
{
    num++;
    records = realloc(records, (num + 1) * sizeof(struct Data));
}

Notice num + 1 instead of num, otherwise you end up writing to a non existent offset in the next iteration when you call fscanf. Also prefer size_t over int when dealing with dynamic memory.

David Ranieri
  • 39,972
  • 7
  • 52
  • 94