简体   繁体   English

结构中的C malloc

[英]C malloc within a struct

I'm trying to malloc a struct with a value read from 3 archives passed by command. 我正在尝试使用从命令传递的3个档案中读取的值来分配一个结构。 I have 3 types of coins whose prices and dates I've turned into arrays, but not dynamically. 我有3种类型的硬币,它们的价格和日期已经变成数组,但不是动态的。 How do I malloc these dates and prices from the struct? 如何从结构中分配这些日期和价格?

Command 命令

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

BTC.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 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;
}

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)); v=(array*)malloc(n_lines*sizeof(array));之后为它们动态分配内存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. 使用完它们后,不要忘记free()它们。

I think you should be allocating n arrays of your array structure. 我认为您应该分配array结构的n数组。 That would be better called coin , or perhaps coin_value (or some sort of Camel_Case name, such as Coin_Value ), but it is the basic entry type. 最好将其称为coin ,或者也许是coin_value (或某种Camel_Case名称,例如Coin_Value ),但这是基本的输入类型。 It's marginally complex because you need an array of 3 arrays of (253) structures, but it is much cleaner than hiding separate arrays inside a structure, not least because it dramatically simplifies the memory allocation (one per file). 这有点复杂,因为您需要由3个(253)结构的数组组成的数组,但是它比在结构内部隐藏单独的数组要干净得多,不仅因为它大大简化了内存分配(每个文件一个)。 Indeed, it would be possible to allocate all the memory at once (and therefore free it at once), but I've not done that. 确实,可以一次分配所有内存(并因此一次释放它),但是我还没有这样做。 The code also doesn't check that the data files all have the same number of lines — it should. 该代码也不会检查数据文件是否都具有相同的行数-应该。 There's also no checking that the date values in corresponding entries match; 也没有检查相应条目中的日期值是否匹配。 again, there probably should be such checking. 再次,可能应该进行这种检查。 When it spots an error, it reports it on standard error and exits. 当发现错误时,它将报告标准错误并退出。

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

This code prints the data two different ways: 此代码以两种不同的方式打印数据:

  1. In N columns across the page. 在整个页面的N列中。
  2. In N groups of entries down the page. 在页面的N组条目中。

On your sample inputs (5 lines, instead of 253 lines): 在样本输入上(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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM