Сохранение файла CSV в массиве с помощью realloc - PullRequest
0 голосов
/ 12 ноября 2018

У меня проблема с чтением данных из CSV-файла и сохранением его в массив.Я хочу сделать это в функции.Значения хороши в функции (чтение работает хорошо), но значения в основном нет.Я думаю, что это проблема с указателями в процессе перераспределения (я могу потерять некоторые из них).Вот мой код и помощь pls.

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));

1 Ответ

0 голосов
/ 13 ноября 2018
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, который указывает на указатель, а затем попытка stick 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 и 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;
    }

    ...
}
...