【问题标题】:Writing with FILE pointer, reading with ifstream用 FILE 指针写,用 ifstream 读
【发布时间】:2013-02-22 08:58:25
【问题描述】:

我必须处理代码,一方面信息使用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) 使用std::ios::in|std::ios::binary 打开ifstream

2) 修复 malloc

【问题讨论】:

  • 您是否考虑过使用 ios::in|ios::binary 打开该流?
  • 该死的打败我@WhozCraig
  • @JasonLarke =P 我什至强调了 =P
  • @WhozCraig:感谢您的快速提示,但这并不能解决我的问题。
  • 您是否尝试过编写一个非常简单的程序?就像你只写一个字符串的 5 行代码一样,关闭 FILE* 然后将其作为流打开,看看是否有效?您为什么要尝试以复杂的方式进行调试?

标签: c++ serialization deserialization ifstream


【解决方案1】:

贴出的代码有几个问题:

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

代码还有其他几个问题;

  • 这是 C 和 C++ 的可怕组合
  • 可避免的显式动态内存管理(不要介意malloc()realloc())。简单地替换为:

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

【讨论】:

  • fwrite 而不是 fputs 完成了这项工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
  • 1970-01-01
  • 2019-10-27
  • 1970-01-01
  • 2013-09-21
相关资源
最近更新 更多