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

Posted

技术标签:

【中文标题】将数据从文件加载到c中的数组【英文标题】:Loading data from a file to an array in c 【发布时间】:2014-11-26 17:38:48 【问题描述】:

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

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

【问题讨论】:

另外,您不需要从intarr_load_binary 返回intarr_t*。你可以直接返回intarr_t 无论如何,您对错误的测试过于谨慎。并且您的 intarr_save_binary 在它有机会关闭文件之前返回。 @BLUEPIXY 我只是想澄清一下。保存 len 是什么意思? @user3121023 添加 fread 后,我需要在加载函数中更改数组的长度吗?如果是这样,我应该将其更改为什么?现在我把它设置为 0。 要加载的记录数。 【参考方案1】:
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

【讨论】:

您可能需要稍微重新安排代码,以便在 I/O 调用后立即处理所有错误,以使代码流更好【参考方案2】:
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

【讨论】:

以上是关于将数据从文件加载到c中的数组的主要内容,如果未能解决你的问题,请参考以下文章

从使用 numpy.save(...) 保存的文件中将 numpy 数组加载到 C 中

如何将 CSV 文件中的数据加载到 numpy 数组中[重复]

C 语言文件操作 ( 学生管理系统 | 命令行接收数据填充结构体 | 结构体写出到文件中 | 查询文件中的结构体数据 )

将数字从文本文件读取到 C 中用户定义函数中的数组

如何将自定义数组保存/重新加载到 plist

使用c#中的流将文件从服务器传输到客户端时数据丢失