0

I'm reading data from a file and need to have a dynamic array of structs based on how many lines are read from the file.

The file I am reading could have up to 5000 lines, and in theory I could just create an array of size 5000, but I see that as inefficient as some files could have only have 10 lines.

The file could hold 5000 participants, and I'd rather make a dynamic array than a fixed one.

My struct which holds all the necessary data members.

A possible solution could be finding number of lines inside text file beforehand, and allocating space for reading.

struct RiderInfo
{
    char name[41];
    int age;
    char raceLength[2];
    double startTime;
    double mountainTime;
    double finishTime;
    int withdrawn;
};
// Allocate space for next element
void allocateParticipant(struct RiderInfo participantList[])
{
    participantList = realloc(participantList, sizeof(struct RiderInfo));
}

// Read file
int readData(struct RiderInfo participantList[], const char filepath[])
{
    // Declare Variables
    int amount = 0, rValue = 0;

    // Declare filepointer
    FILE* fp = fopen(filepath, "r");

    // Continue to loop while return of readfile is correct
    while (rValue == 0)
    {
        allocateParticipant(participantList);
        // Read one line file, rValue is the return (if return of 1 eof reached)
        rValue = readFileRecord(fp, &participantList[amount]);
        amount++;
    }

    return amount;

}

// Free memory
void freeMemory(struct RiderInfo participantList[])
{
    free(participantList);
}

int main(void)
{

    // Declare struct array to hold each participants values
    struct RiderInfo participant[] = { 0 };

    // Declare filename for data
    const char datafile[] = "data.txt";

    // Read data from file and save return in size
    int size = readData(&participant, datafile);

    // Output Data
    for (i = 0; i < size; i++)
    {
        printParticipant(&participant[i], 0);
    }

    // Free all used memory before exit
    freeMemory(&participant);

    //Exit
    return 0;

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Use `malloc()` to allocate a dynamic array, and `realloc()` to increase the size. – Barmar Apr 12 '20 at 02:44
  • 1
    SO is not a tutoring service. You need to read a tutorial on the use of malloc, realloc, and free. – Barmar Apr 12 '20 at 02:44
  • *"The file i am reading could have up to 5000 lines, in theory i could just create an array of size 5000 but i see that as inefficient as some files could have only have 10 lines."* Who cares, 5000 times 88 bytes per record is less than half a megabyte. Just allocate all the space you could need and forget about it, this much memory isn't worth optimizing. – John Zwinck Apr 12 '20 at 02:45
  • `rValue = readFileRecord(fp, &participantList[ammount]); ammount++;` is conceptually wrong. Only increment if `rValue == 0`. – chux - Reinstate Monica Apr 12 '20 at 02:51
  • Since you do not return a value in `void allocateParticipant(struct RiderInfo participantList[])` to assign to the original pointer back in the caller, you must pass the *address of* `participantList` in order for the change to be preserved after the function return -- otherwise you are simply reallocating with a copy of the pointer and all changes are lost when the function returns. – David C. Rankin Apr 12 '20 at 04:24
  • @JohnZwinck - unless you are working on an embedded system with limited memory available. – David C. Rankin Apr 12 '20 at 04:26
  • @PeterMortensen -- would you like to write up an answer -- it probably needs one. I will defer to you. Possible duplicate [Pointer to pointer of structs indexing out of bounds(?) when I try to index anything other than zero](https://stackoverflow.com/a/60639540/3422102) – David C. Rankin Jul 19 '20 at 07:05

0 Answers0