【问题标题】:ifstream / ofstream issue with c++?c++ 的 ifstream / ofstream 问题?
【发布时间】:2013-09-20 06:03:10
【问题描述】:

我一直很难写入二进制文件并回读。我基本上是在写这种格式的记录

1234|ABCD|efgh|IJKL|ABC

在写入这条记录之前,我会写入整个记录的长度(using string.size()),然后我使用ofstream 将记录写入二进制文件,如下所示:

整数大小;

ofstream studentfile;
studentfile.open( filename.c_str(),ios::out|ios::binary );
studentfile.write((char*)&size,sizeof(int));
     studentfile.write(data.c_str(),(data.size()*(sizeof(char))));
     cout << "Added " << data << " to " << filename << endl;
     studentfile.close();

我在其他地方读到了这些数据

ifstream ifile11;
     int x;
     std::string y;
     ifile11.open("student.db", ios::in |ios::binary);
     ifile11.read((char*)&x,sizeof(int));
     ifile11.read((char*)&y,x);
     cout << "X " << x << " Y " << y << endl;

首先我将记录的长度读入变量x,然后将记录读入字符串y。问题是,输出显示 x 为 '0' 而 'y' 为空。

我无法弄清楚这一点。非常感谢能够研究这个问题并提供一些见解的人。

谢谢

【问题讨论】:

    标签: c++ binaryfiles binary-data ifstream ofstream


    【解决方案1】:

    您不能那样读取字符串,因为std::string 实际上只是一个指针和一个大小成员。 (试试std::string s; sizeof(s),不管你把字符串设置成什么大小都是不变的。)

    而是将其读入一个临时缓冲区,然后将该缓冲区转换为字符串:

    int length;
    ifile11.read(reinterpret_cast<char*>(&length), sizeof(length));
    
    char* temp_buffer = new char[length];
    ifile11.read(temp_buffer, length);
    
    std::string str(temp_buffer, length);
    delete [] temp_buffer;
    

    【讨论】:

    • 您能详细说明一下吗?谢谢
    • @SasankaPanguluri 更新了答案。
    • @SasankaPanguluri 您是否尝试过在十六进制编辑器或类似工具中检查文件的内容?
    • 我能理解的只是它正在被写入。你能告诉我是否有办法知道它正在写入正确的数据吗?
    • @SasankaPanguluri 您可能想在调试器中运行编写程序,并检查size 变量是否实际设置正确。否则,我通常会通过对文件进行十六进制转储来检查这些内容,以查看文件是否正常。您应该有四个字节的长度,其中第一个(或大端系统的最后一个)应该是非零,然后是您的字符串。
    【解决方案2】:

    我知道我正在回答我自己的问题,但我坚信这些信息会对每个人都有帮助。在大多数情况下,约阿希姆的回答是正确且有效的。但是,我的问题背后有两个主要问题:

    1. The Dev-C++ compiler was having a hard time reading binary files.
    
    2. Not passing strings properly while writing to the binary file, and also reading from the file. For the reading part, Joachim's answer fixed it all.
    

    Dev-C++ IDE 没有帮助我。它错误地从二进制文件中读取数据,甚至没有使用 temp_buffer。 Visual C++ 2010 Express 已正确识别此错误,并抛出运行时异常,避免我被误导。 一旦我将所有代码放入一个新的 VC++ 项目中,它就会适当地向我提供错误消息,以便我可以修复它。

    所以,请不要使用 Dev-C++,除非你想遇到像这样的真正麻烦。此外,在尝试读取字符串时,Joachim 的答案将是理想的方式。

    【讨论】:

    • 请不要盲目地将 Dev-C++ 等同于旧的和有缺陷的。 sourceforge.net/projects/orwelldevcpp
    • 对不起,如果这意味着诽谤。有一次我很确定。我帮不上什么忙。我在 Dev-C++ 上的编译器至少不能正确读取二进制文件。我不知道任何确切的原因。