-1

我必须处理一方面信息被写入文件的代码,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

4

1 回答 1

2

发布的代码存在一些问题:

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

代码还有其他几个问题;

  • 它是 C 和 C++ 的可怕组合
  • malloc()可避免的显式动态内存管理(没关系realloc())。简单地替换为:

    char posBuf[sizeof(int) + 2 * sizeof(double)];
    
  • while (!feof(inFile)).
  • 实际上没有检查 I/O 操作是否成功
于 2013-02-22T09:13:07.580 回答