Search code examples
carrayscsvmallocarchive

C malloc within a struct


I'm trying to malloc a struct with a value read from 3 archives passed by command. I have 3 types of coins whose prices and dates I've turned into arrays, but not dynamically. How do I malloc these dates and prices from the struct?

Command

a.exe BTC.csv NEO.csv IOT.csv

BTC.csv

253   
02/20/18,11403.7   
02/19/18,11225.3   
02/18/18,10551.8   
02/17/18,11112.7   
02/16/18,10233.9  
 ...

NEO.csv

253    
02/20/18,128.36    
02/19/18,137.47    
02/18/18,127.38    
02/17/18,136.75    
02/16/18,128.85   
...

IOT.csv

253    
2/20/18,1.91    
2/19/18,2.09    
2/18/18,1.98   
2/17/18,2.2   
2/16/18,2.1   
...

Code:

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

typedef struct
{
    int month;
    int day;
    int year;
    double value;
}array;

typedef struct
    {   //I want allocate these arrays dynamically
    int month[253];
    int day[253];
    int year[253];
    double newvalue[253];
}coin;

int main(int argc, char *argv[]){
    FILE *csv;
    char string[9];
    long int n_lines=0;
    int n = argc-1;

    coin *m = (coin*)malloc(n*sizeof(coin));

    for(int z=1; z<argc; z++)
       {
        sprintf(string, "%s", argv[z]);

        if((csv=fopen(string, "r")) == NULL)
        {
            printf("%s not found\n", string);
            exit(1);
        }

        fscanf(csv, "%li", &n_lines); //n_lines=253

        array *v;
        v=(array*)malloc(n_lines*sizeof(array));

        char line[256];
        int i=0;

        while (fgets(line, 256, csv) != NULL && i<n_lines)
        {
                int count = fscanf(csv, "%d/%d/%d,%lf", &v[i].month, &v[i].day, &v[i].year, &v[i].value);

                m[z-1].month[i] = v[i].month;
                m[z-1].day[i] = v[i].day;
                m[z-1].year[i] = v[i].year;
                m[z-1].newvalue[i] = (v[i].value)/2;
                i++;
        }

        free(v);

        fclose(csv); 

    }

    for(int z=1;i<argc;z++)
    {
        for(int i=0;i<n_lines;i++)
        {
           printf("%0.2d/%0.2d/%0.2d  %lf\n", m[z-1].month[i], m[z-1].day[i], m[z-1].year[i], m[z-1].newvalue[i]);
        }
    }

    return 0;
}

Solution

  • Instead of setting up your struct as a bunch of arrays:

    typedef struct
    {   //I want allocate these arrays dynamically
        int month[253];
        int day[253];
        int year[253];
        double newvalue[253];
    
    }coin;
    

    Just use pointers:

    typedef struct
    {
        int *month;
        int *day;
        int *year;
        double *newvalue;
    } coin;
    

    And dynamically allocate memory for them after v=(array*)malloc(n_lines*sizeof(array));:

    coin c;
    c.month = malloc(n_lines * sizeof(int));
    c.day = malloc(n_lines * sizeof(int));
    c.year = malloc(n_lines * sizeof(int));
    c.newvalue = malloc(n_lines * sizeof(double));
    

    Don't forget to free() them once you're done using them.