使用FILE指针写入,使用ifstream读取

时间:2013-02-22 08:58:25

标签: c++ serialization deserialization ifstream

我必须处理代码,其中一方使用FILE*将信息写入文件,另一方面使用ifstream读取。

我尝试编译一个显示与原始代码相同行为的虚拟代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>

int main()
{

    FILE* outFile = fopen("testFile", "w");  
    char* posBuf = NULL;                                                       
    unsigned int counter = 0;                           

    posBuf = (char*) malloc( sizeof(int) + 2*sizeof(double) );

    int iDummy = 123;
    memcpy(posBuf+counter, (const void*) &iDummy, sizeof(int));          
    counter += sizeof(int);                           

    double dDummy = 456.78;
    memcpy(posBuf+counter, (const void*) &dDummy, sizeof(double));            

    counter += sizeof(double);
    dDummy = 111.222;
    memcpy(posBuf+counter, (const void*) &dDummy, sizeof(double));            

    fputs(posBuf, outFile);   
    fclose(outFile);          

    /////////////////////

    std::ifstream myfile; 
    myfile.open("testFile", std::ios::in|std::ios::binary);

    myfile.seekg (0, std::ios::end);                        
    unsigned int length = myfile.tellg();              
    myfile.seekg (0, std::ios::beg);                        

    char* posBuf2 = (char*) malloc( length );           
    myfile.read(posBuf2, length);                       

    counter = 0;
    int idummy = 0;
    memcpy((void*) &idummy, posBuf2+counter, sizeof(int));  
    counter += sizeof(int);                                       
    printf("read integer: %u\n", idummy);            

    double ddummy = 1.0;
    memcpy((void*) &ddummy, posBuf2+counter, sizeof(double));                 
    counter += sizeof(double);                                       
    printf("read double: %f\n", ddummy);                                      

    ddummy = 1.0;
    memcpy((void*) &ddummy, posBuf2+counter, sizeof(double));                 
    counter += sizeof(double);                                       
    printf("read double: %f\n", ddummy);                                      

    myfile.close();

    /////////////////////

    FILE* inFile = fopen("testFile", "r");
    char* posBuf3 = NULL;

    unsigned int c = 0;
    while ( ! feof (inFile) )
    {
        posBuf3 = (char*) realloc((void*) posBuf3, c+4);
        fgets(posBuf3+c, 4, inFile);
        c += 4;
    }

    idummy = 0;
    memcpy((void*) &idummy, posBuf, sizeof(int));
    printf("read again integer: %u\n", idummy);

    ddummy =1.0;
    memcpy((void*) &ddummy, posBuf+sizeof(int), sizeof(double));
    printf("read again double: %f\n", ddummy);

    ddummy =1.0;
    memcpy((void*) &ddummy, posBuf+sizeof(int)+sizeof(double), sizeof(double));
    printf("read again double: %f\n", ddummy);

    return 0;
}

我得到的输出是:

read integer: 123
read double: 0.000000
read double: 0.000000
read again integer: 123
read again double: 456.780000
read again double: 111.222000

正如您所看到的,仅当我使用FILE*来读取文件时,反序列化才有效。

问题:对该行为有何解释?

谢谢!

已更新

1)使用ifstream

打开std::ios::in|std::ios::binary

2)修复malloc

1 个答案:

答案 0 :(得分:2)

发布代码的一些问题:

  • 写入超出为posBuf分配的内存范围(1 int和2 double被复制到内存中,但只分配sizeof(int) + sizeof(double)) ,这是未定义的行为。
  • fputs()将其参数视为以空字符结尾的字符串,因此在遇到空字符时将停止写入。以二进制模式打开文件并使用fwrite()而不是将其输入视为空终止字符串。

代码还有其他几个问题;

  • 这是一个可怕的C和C ++混合
  • 可避免的显式动态内存管理(不要介意malloc()realloc())。只需替换为:

    char posBuf[sizeof(int) + 2 * sizeof(double)];
    
  • while (!feof(inFile))
  • 实际上没有检查I / O操作是否成功