2017-02-06 1 views
0

Я борюсь с чтением поплавков из файла, который я создал во время жизни программы. Я пытался перемотать файл, я пытался открыть и закрыть файл перед его чтением, я пытался ставить значения непосредственно в таблице и другой переменной. Idk, что я могу сделать больше, что здесь не так?Как читать поплавки из файла в c?

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main(void) { 
    srand(time(NULL)); 

    float *tab; 
    float x = 0.0; 
    int i, size; 
    FILE *fp; 

    fp = fopen("data.txt", "w+"); 
    if (fp == NULL) { 
     printf("Error"); 
     system("PAUSE"); 
     exit(1); 
    } 
    printf("Size of table: "); 
    scanf("%d", &size); 

    tab = (int*)malloc(size * sizeof(int)); 

    for (i = 0; i < size; i++) { 
     tab[i] = (8.0 - 2.0) * (float)rand()/RAND_MAX + 2.0; 
     fprintf(fp, "%.2f ", tab[i]); 
    } 
    for (i = 0; i < size; i++) { 
     printf("%.2f ", tab[i]); 
    } 
    printf("\n"); 

    fp = fclose; 
    fp = fopen("data.txt", "w+"); 
    tab = realloc(tab, 2*size); 

    for (i = 0; i < size * 2; i+=2) { 
     fscanf(fp, "%f", &x); 
     printf("%.2f ", x); 
     //tab[i + 1] = tab[i]/2; 
    } 

    /*for (i = 0; i < size * 2; i++) { 
     printf("%.2f \n", tab[i]); 
    }*/ 


    fp = fclose; 
    printf("\n"); 
    system("PAUSE"); 
    return 0; 
} 
+6

Ну, теперь. Если у вас есть вкладка 'float * ', как и вы, то почему вы думаете:' tab = (int *) malloc (size * sizeof (int)); 'делает какой-то смысл? Такой код, вероятно, закончится «работой», но, очевидно, это вызывает много путаницы. – unwind

+0

Да, вы правы, моя ошибка. Но это не влияет на чтение из файла. Проблема такая же :( – soommy12

+0

@xing does not work – soommy12

ответ

1

В этом коде есть ряд проблем. Во-первых, как отмечено в комментариях, первоначальное распределение неверно. Вы занимаете место для float s, а не int s. Вы могли бы избежать этой проблемы полностью, если бы вы написали вызов malloc() так:

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

Здесь результат malloc() не литой, since it is not necessary in C. Также обратите внимание, что вместо использования явного типа для аргумента для оператора sizeof вместо этого используется идентификатор. Это гарантирует, что независимо от типа tab, который должен быть указателем, результат sizeof будет правильным. Кроме того, вы всегда должны проверить, было ли выделение успешным.

fp = fclose просто неправильно. Это должно быть fclose(fp). После этого, когда вы снова открываете файл с "w+", файл обрезается до нулевой длины, и вы теряете ранее записанные данные. Поскольку файл уже открыт с "w+", просто используйте rewind(fp) здесь.

Для перераспределения, которое вы делаете, помимо этого аргументы здесь не совсем правы, существует потенциальная проблема, о которой вы должны знать. realloc() может возвращать нулевой указатель в случае ошибки распределения. Если это произойдет, и вы прямо назначаете результат realloc() указателю, для которого вы перераспределяете (tab), тогда вы потеряете ссылку на ранее выделенную память. Это утечка памяти и потерянные данные. Способ сделать это - сохранить результат realloc() во временном указателе, который вы тестируете. Если временный указатель является нулевым указателем, произошла ошибка; в противном случае вы можете безопасно назначить возвращаемое значение исходному указателю.

И как уже отмечалось, когда вы звоните fclose() в последний раз, это должно быть fclose(fp).

Вот модифицированный код:

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main(void) { 
    srand(time(NULL)); 

    float *tab, *temp;   // added temp for realloc() check 
    float x = 0.0; 
    int i, size; 
    FILE *fp; 

    fp = fopen("data.txt", "w+"); 
    if (fp == NULL) { 
     printf("Error"); 
     system("PAUSE"); 
     exit(1); 
    } 
    printf("Size of table: "); 
    scanf("%d", &size); 

    /* You should always check for allocation errors */ 
    if ((tab = malloc(sizeof(*tab) * size)) == NULL) { 
     fprintf(stderr, "Error in initial allocation\n"); 
     exit(EXIT_FAILURE); 
    } 

    for (i = 0; i < size; i++) { 
     tab[i] = (8.0 - 2.0) * (float)rand()/RAND_MAX + 2.0; 
     fprintf(fp, "%.2f ", tab[i]); 
    } 
    for (i = 0; i < size; i++) { 
     printf("%.2f ", tab[i]); 
    } 
    printf("\n"); 

// fclose(fp);      // not fp = fclose; 
// fp = fopen("data.txt", "w+"); // when you reopen, the file is truncated 
    rewind(fp);      // but just do this 

    /* Fixed this reallocation */ 
    temp = realloc(tab, sizeof(*tab) * size * 2);  
    if (temp == NULL) { 
     fprintf(stderr, "Error in reallocation\n"); 
     exit(EXIT_FAILURE); 
    } 
    tab = temp; 

    for (i = 0; i < size * 2; i+=2) { 
     fscanf(fp, "%f", &x); 
     printf("%.2f ", x); 
     //tab[i + 1] = tab[i]/2; 
    } 

    /*for (i = 0; i < size * 2; i++) { 
     printf("%.2f \n", tab[i]); 
    }*/ 


    fclose(fp);   // not fp = fclose; 
    printf("\n"); 
    system("PAUSE"); 
    return 0; 
} 

Пример взаимодействия:

Size of table: 10 
2.65 5.67 5.21 3.22 3.07 4.29 5.96 5.96 5.15 7.36 
2.65 5.67 5.21 3.22 3.07 4.29 5.96 5.96 5.15 7.36