2014-11-26 1 views
0

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

intarr_t* intarr_load_binary(const char* filename) 
{ 
    unsigned int len = 0; 
    FILE *f = fopen (filename, "rb"); 
    fscanf (f, "%d", len); 
    intarr_t* newia = malloc (sizeof(intarr_t)); 
    assert (newia); 
    newia->data = malloc (len*sizeof(int)); 
    assert(newia->data); 
    newia->len = len; 
    if (f != NULL) 
    { 
     while (!feof(f)) 
     { 
      fscanf (f, "%d", newia->data); 
     } 
    } 
    else 
    { 
     return NULL; 
    } 
    fclose (f); 
    return newia; 
} 

структура, которую я использовал для сохранения/загрузки здесь:

typedef struct { 
    int* data; 
    unsigned int len; 
} intarr_t; 

код, который я использовал, чтобы сохранить файл здесь:

int intarr_save_binary(intarr_t* ia, const char* filename) 
{ 
    unsigned int len = ia->len; 
    FILE *f; 
    f = fopen (filename, "wb"); 
    if (fwrite (ia->data, sizeof(int), len, f) == len) 
    { 
     return 0; 
    } 
    else 
    { 
     return 1; 
    } 
    fclose (f); 
} 
+2

и сохраните 'len'. – BLUEPIXY

+1

Кроме того, вам не нужно возвращать 'intarr_t *' из 'intarr_load_binary'. Вы можете просто вернуть 'intarr_t'. –

+0

В любом случае, вы слишком часто проверяете ошибки. И ваш 'intarr_save_binary' возвращается до того, как появится возможность закрыть файл. – Deduplicator

ответ

0
the code is writing no length (len) value as the first data item to the file 
yet the code is reading a length (len) value 
as if it were the first data item in the file. 

this code is full of errors and oversights: 

int intarr_save_binary(intarr_t* ia, const char* filename) 
{ 
    unsigned int len = ia->len; 
    FILE *f; 
    f = fopen (filename, "wb"); 
    if (fwrite (ia->data, sizeof(int), len, f) == len) 
    { 
     return 0; 
    } 
    else 
    { 
     return 1; 
    } 
    fclose (f); 
} 

suggest using code similar to this: 

int intarr_save_binary(intarr_t* ia, const char* filename) 
{ 
    int returnValue = 0; 
    unsigned int len = ia->len; 
    FILE *f; 

    if(NULL == (f = fopen (filename, "wb")) 
    { 
     perror("fopen failed"); 
     returnValue = 1; 
    } 

    else if (fwrite (&len, sizeof(int), 1, f) == 1) 
    { // then write of length successful 

     if (fwrite (ia->data, sizeof(int), len, f) == len) 
     { 
      returnValue = 0; // indicate success 
     } 

     else 
     { // else, write of data failed 
      returnValue = 3; 
     } 
    } 
    else 
    { // else, failed to write len value to file 
     returnValue = 4; 
    } 

    fclose(f); // cleanup (writes last buffer to file) 
    return(returnValue); 
} // end function: intarr_save_binary 
+0

, вы можете немного изменить порядок кода, чтобы все ошибки обрабатывались сразу после вызова ввода-вывода, чтобы улучшить поток кода – user3629249

0
this code needs some work. 
for instance because assert should not enabled in production code 
and error conditions not being checked 
and cleanup not being properly performed 

if the program is ok to continue after an I/O error 
by always returning NULL 
then you could change the following, 
to return NULL rather than exiting the program 

intarr_t* intarr_load_binary(const char* filename) 
{ 
    unsigned int len = 0; 
    FILE *f = fopen (filename, "rb"); 
    fscanf (f, "%d", len); 
    intarr_t* newia = malloc (sizeof(intarr_t)); 
    assert (newia); 
    newia->data = malloc (len*sizeof(int)); 
    assert(newia->data); 
    newia->len = len; 
    if (f != NULL) 
    { 
     while (!feof(f)) 
     { 
      fscanf (f, "%d", newia->data); 
     } 
    } 
    else 
    { 
     return NULL; 
    } 
    fclose (f); 
    return newia; 
} 

suggest: 

intarr_t* intarr_load_binary(const char* filename) 
{ 
    unsigned int len = 0; 
    FILE *f = NULL; 
    intarr_t* newia = NULL; 

    if(NULL == fopen (filename, "rb")) 
    { // then, fopen failed 
     perror("fopen failed"); 
     exit(EXIT_FAILURE); 
    } // end if 

    // implied else, fopen successful 

    if(NULL == (newia = malloc (sizeof(intarr_t))) 
    { // then malloc failed 
     perror("malloc failed"); 
     fclose(f); 
     exit(EXIT_FAILURE); 
    } // end if 

    // implied else, malloc successful 

    if((fread (&len, sizeof(int), 1, f) != 1)) 
    { // then fread failed 
     perror("fread failed"); 
     fclose(f); 
     free(newia); 
     exit(EXIT_FAILURE); 
    } // end if 

    // implied else, fread for len successful 

    newis->len = len; 

    if(NULL == (newia->data = malloc (len*sizeof(int)))) 
    { // then malloc failed 
     perror("malloc failed"); 
     fclose(f); 
     free(newia); 
     exit(EXIT_FAILURE); 
    } // end if 

    // implied else, malloc successful 

    if(fread(newia->data, sizeof(int), len, f) != len) 
    { // then, fread failed 
     perror("fread failed"); 
     fclose(f); 
     free(newia->data)l 
     free(newia); 
     exit(EXIT_FAILURE); 
    } // end if 

    // implied else, fread successful 

    fclose (f); 
    return newia; 
} // end function: intarr_load_binary 
Смежные вопросы