在c中将数据从文件加载到数组

时间:2014-11-26 17:38:48

标签: c arrays file load save

我想从之前保存的文件中加载数组。我运行下面的代码,但由于某种原因,当我加载数组时,我加载的数组长度与我保存的数组的长度不同。我如何更改加载文件代码的长度,以便它适用于任何数组长度?

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 个答案:

答案 0 :(得分: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

答案 1 :(得分: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