结构中的C malloc

时间:2018-03-29 00:29:33

标签: c arrays csv malloc archive

我尝试使用从命令传递的3个档案中读取的值来malloc结构。我有3种类型的硬币,其价格和日期我已变成数组,但不是动态的。如何从结构中对这些日期和价格进行malloc?

  

命令

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   
...

代码:

#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;
}

2 个答案:

答案 0 :(得分:3)

而不是将结构设置为一堆数组:

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

}coin;

只需使用指针:

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

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));

在您使用它们后,不要忘记free()

答案 1 :(得分:2)

我认为您应该分配n结构的array数组。那会更好地称为coin,或者可能是coin_value(或某种类型的Camel_Case名称,例如Coin_Value),但它是基本的条目类型。它有点复杂,因为你需要一个包含3个(253)结构数组的数组,但它比在结构中隐藏单独的数组要清晰得多,这不仅仅是因为它大大简化了内存分配(每个文件一个)。实际上,可以一次分配所有内存(因此可以立即释放它),但我没有这样做。代码也没有检查数据文件是否都具有相同的行数 - 它应该。还没有检查相应条目中的日期值是否匹配;再次,可能应该有这样的检查。当它发现错误时,它会报告标准错误并退出。

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

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

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

    Coin_Value **m = (Coin_Value **)malloc(n * sizeof(*m));
    if (m == 0)
    {
        fprintf(stderr, "Memory allocation failure (%zu bytes)\n", n * sizeof(*m));
        exit(1);
    }

    /* Should check that number of lines in each file is consistent */
    for (int z = 1; z < argc; z++)
    {
        if ((csv = fopen(argv[z], "r")) == NULL)
        {
            fprintf(stderr, "%s not found\n", argv[z]);
            exit(1);
        }

        if (fscanf(csv, "%li", &n_lines) != 1)
        {
            fprintf(stderr, "failed to read a number from %s\n", argv[z]);
            exit(1);
        }
        if (n_lines <= 0 || n_lines > 1000)
        {
            fprintf(stderr, "number of lines in %s out of control (got %ld)\n", argv[z], n_lines);
            exit(1);
        }

        /* Gobble any trailing data and newline */
        int c;
        while ((c = getc(csv)) != EOF && c != '\n')
            ;

        Coin_Value *v = (Coin_Value *)malloc(n_lines * sizeof(*v));
        if (v == 0)
        {
            fprintf(stderr, "Memory allocation failure (%zu bytes)\n", n_lines * sizeof(*v));
            exit(1);
        }

        char line[256];
        for (int i = 0; fgets(line, sizeof(line), csv) != NULL && i < n_lines; i++)
        {
            if (sscanf(line, "%d/%d/%d,%lf", &v[i].month, &v[i].day, &v[i].year, &v[i].value) != 4)
            {
                fprintf(stderr, "Format error processing line: %s", line);
                exit(1);
            }
        }

        m[z-1] = v;

        fclose(csv);
    }

    /* Multi-column output */
    putchar('\n');
    for (int z = 1; z < argc; z++)
        printf("%s%19.3s", (z == 1) ? "" : "   ", argv[z]);
    putchar('\n');

    for (long i = 0; i < n_lines; i++)
    {
        for (int z = 1; z < argc; z++)
        {
            printf("%s%.2d/%.2d/%.2d  %9.2f", (z == 1) ? "" : "   ",
                   m[z - 1][i].month, m[z - 1][i].day, m[z - 1][i].year, m[z - 1][i].value);
        }
        putchar('\n');
    }
    putchar('\n');

    for (int z = 1; z < argc; z++)
    {
        printf("%.3s:\n", argv[z]);
        for (long i = 0; i < n_lines; i++)
        {
            printf("%.2d/%.2d/%.2d  %9.2f\n",
                   m[z - 1][i].month, m[z - 1][i].day, m[z - 1][i].year, m[z - 1][i].value);
        }
        putchar('\n');
    }

    for (int z = 1; z < argc; z++)
        free(m[z-1]);
    free(m);

    return 0;
}

此代码以两种不同的方式打印数据:

  1. 在页面的N列中。
  2. 在页面下方的N组条目中。
  3. 在您的样本输入上(5行,而不是253行):

                    BTC                   NEO                   IOT
    02/20/18   11403.70   02/20/18     128.36   02/20/18       1.91
    02/19/18   11225.30   02/19/18     137.47   02/19/18       2.09
    02/18/18   10551.80   02/18/18     127.38   02/18/18       1.98
    02/17/18   11112.70   02/17/18     136.75   02/17/18       2.20
    02/16/18   10233.90   02/16/18     128.85   02/16/18       2.10
    
    BTC:
    02/20/18   11403.70
    02/19/18   11225.30
    02/18/18   10551.80
    02/17/18   11112.70
    02/16/18   10233.90
    
    NEO:
    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:
    02/20/18       1.91
    02/19/18       2.09
    02/18/18       1.98
    02/17/18       2.20
    02/16/18       2.10