使用 realloc 将 CSV 文件保存在数组中
CSV file saving in array with realloc
我在从 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);
tab 早先在 main 中分配为
double *tab;
tab = malloc(1*sizeof(*tab));
double *tab;
tab = malloc(1*sizeof(*tab));
temp = realloc(*tab, i*sizeof(**tab));
这些为指针分配 space,但您存储的双精度数通常更大。所以你需要...
tab = malloc(1*sizeof(*tab));
temp = realloc(*tab, i * sizeof(double));
**(tab + i - 2) = A;
**(tab + i - 1) = B;
这也不对。它添加到 tab
的地址,它指向一个指针,然后尝试在只有 space 作为一个指针的地方添加 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
and fscanf
.
的众多问题之一
相反,使用 fgets
和 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;
}
...
}
我在从 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);
tab 早先在 main 中分配为
double *tab;
tab = malloc(1*sizeof(*tab));
double *tab;
tab = malloc(1*sizeof(*tab));
temp = realloc(*tab, i*sizeof(**tab));
这些为指针分配 space,但您存储的双精度数通常更大。所以你需要...
tab = malloc(1*sizeof(*tab));
temp = realloc(*tab, i * sizeof(double));
**(tab + i - 2) = A;
**(tab + i - 1) = B;
这也不对。它添加到 tab
的地址,它指向一个指针,然后尝试在只有 space 作为一个指针的地方添加 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
and fscanf
.
相反,使用 fgets
和 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;
}
...
}