首页 > 解决方案 > 使用 realloc 将 CSV 文件保存在数组中

问题描述

我从 csv 文件中读取数据并将其保存到数组中时遇到问题。我想在一个函数中做到这一点。价值在功能上很好(阅读效果很好),但主要价值不是。我认为这是重新分配过程中指针的问题(我可能会丢失其中一些)。这是我的代码,请帮忙。

void read_from_csv(FILE* file ,double **tab, int *size)  
{
    int i = 0;
    double A, B;
    double *temp;
    while (fscanf(file, "%lf;%lf\n", &A, &B) != EOF)
    {
        i += 2;
        temp = realloc(*tab, i*sizeof(**tab));
        if (temp != NULL)
        {
            *tab = temp;
            *size = i;
            **(tab + i - 2) = A;
            **(tab + i - 1) = B;
        }
        else
        {
            printf("\nERROR");
            temp = NULL;
        }   
    }
}

我主要这样称呼它:

file = fopen("file.csv", "r");

read_from_csv(file,&tab,&size);

fclose(file);

选项卡在 main 之前分配为

double *tab;
tab = malloc(1*sizeof(*tab));

标签: cfilecsvpointersrealloc

解决方案


double *tab;
tab = malloc(1*sizeof(*tab));

temp = realloc(*tab, i*sizeof(**tab));

这些为指针分配空间,但您存储的双精度通常更大。所以你需要...

tab = malloc(1*sizeof(*tab));

temp = realloc(*tab, i * sizeof(double));

**(tab + i - 2) = A;
**(tab + i - 1) = B;

这也不太对。它添加到tab指向指针的地址,然后在只有一个指针空间的地方尝试粘贴 2 双打。

相反,您想添加*tab分配内存的地址,然后取消引用它。

*(*tab + i - 2) = A;
*(*tab + i - 1) = B;

使用*tab数组做同样的事情并且更容易阅读。

(*tab)[i - 2] = A;
(*tab)[i - 1] = B;

while (fscanf(file, "%lf;%lf\n", &A, &B) != EOF)

这也不太对。如果它总是看到正确的输入,那很好。但是,如果它看到某些东西,它不会期望它会挂起。fscanf如果解析失败,将不会推进游标。它会一遍又一遍地重复读取相同的坏行。无论垃圾在里面A还是B会进入的tab。这是 和 的众多问题scanf之一fscanf

fgets相反,使用and将读取与解析行分开sscanf。这避免了垃圾数据并允许更好地处理坏行。

char line[BUFSIZ];
while (fgets(line, sizeof(line), file) != NULL)
{
    if( sscanf(line, "%lf;%lf\n", &A, &B) != 2 ) {
        fprintf(stderr, "%s could not be parsed\n", line);
        continue;
    }

    ...
}

推荐阅读