结构中的 C malloc
C malloc within a struct
我正在尝试 malloc 一个结构,其值是从命令传递的 3 个档案中读取的。我有 3 种类型的硬币,它们的价格和日期已变成数组,但不是动态的。我如何从结构中分配这些日期和价格?
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
...
代码:
#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;
}
而不是将结构设置为一堆数组:
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()
用完它们。
我认为您应该为 array
结构分配 n
数组。将其称为 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;
}
此代码以两种不同的方式打印数据:
- 在整个页面的 N 列中。
- 在页面下方的 N 组条目中。
在您的样本输入上(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
我正在尝试 malloc 一个结构,其值是从命令传递的 3 个档案中读取的。我有 3 种类型的硬币,它们的价格和日期已变成数组,但不是动态的。我如何从结构中分配这些日期和价格?
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
...
代码:
#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;
}
而不是将结构设置为一堆数组:
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()
用完它们。
我认为您应该为 array
结构分配 n
数组。将其称为 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;
}
此代码以两种不同的方式打印数据:
- 在整个页面的 N 列中。
- 在页面下方的 N 组条目中。
在您的样本输入上(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