【发布时间】:2018-09-03 03:44:44
【问题描述】:
所以我成功读取了这样的 CSV 文件(CSV 文件有 4 列 x,y,u,v )-
while(4 == fscanf(fp, "%f %f %f %f\n", &d.xvalue, &d.yvalue, &d.uvalue, &d.vvalue))
{
dataset = realloc(dataset, sizeof(*dataset) * (total + 1));
dataset[total] = d;
total++;
}
结构 -
typedef struct {
double xvalue;
double yvalue;
double uvalue;
double vvalue;
} flow_data;
但是对于大型 CSV 文件,它执行了 100,000 次以上的重新分配。我试图将其简化为类似的内容,但现在根本无法阅读。
// Reading flow_data.csv
FILE* fp = fopen(flow_file, "r");
// Checking if the file has been read succesfully
if( fp == NULL)
{
perror("Error opening file");
exit(1);
}
char buf[500];
fgets(buf, sizeof(buf), fp); // Skip the first line
int total = 0;
int buf_size = INITIAL_SIZE;
flow_data d;
flow_data* dataset = (flow_data*)malloc(sizeof(flow_data) * buf_size);
while(4 == fscanf(fp, "%lf, %lf, %lf, %lf\n", &d.xvalue, &d.yvalue, &d.uvalue, &d.vvalue))
{
if (d.xvalue >= 0)
{
if (total >= buf_size) {
buf_size = buf_size * 2;
dataset = realloc(dataset,buf_size * sizeof(flow_data));
if (dataset == NULL) {
printf("error allocating memory!\n");
exit(EXIT_FAILURE);
}
}
dataset[total] = d;
total++;
}
}
只有当 X 值大于 20 时才会读取该行。我做错了什么?
【问题讨论】:
-
您的
dataset[total] = d分配和d.xvalue >= 20检查似乎在您的total + 1 == buf_size块内。您需要调整括号,以便在每个循环中都进行分配和退出检查,而不是仅在调整缓冲区大小时进行。 -
是的,我已经解决了这个问题,但仍然是同样的问题。
-
您可以使用 fseek 跳过字节。
-
那会代替 fscanf 吗?
-
请阅读有关创建 MCVE (minimal reproducible example) 的信息。我们只需要第二个例子。我可能应该删除我的评论,因为您的第二个示例或多或少符合我的建议。它没有显示的是
INITIAL_SIZE——最好是零。您还需要注意不要泄漏内存:使用some_ptr = realloc(some_ptr, new_size);是不好的,因为如果realloc()失败,some_ptr被分配 NULL,这意味着以前的数据不再可访问。使用new_ptr = realloc(old_ptr, new_size); if (new_ptr == NULL) { …out of memory… } old_ptr = new_ptr; old_size = new_size;或类似名称。