【问题标题】:Cannot read simple binary integers from file? (C++)无法从文件中读取简单的二进制整数? (C++)
【发布时间】:2011-06-07 07:54:30
【问题描述】:

我的代码是这样的:

更新

#include <iostream>
#include <fstream>

using namespace std;

int main(int argc, char **argv)
{
  ifstream r("foo.bin", ios::binary);
  ofstream w("foo.bin", ios::binary);
  int i;

  int ints[10] = {0,1,2,3,4,5,6,8,9};
  w.write((char*)&ints, sizeof(ints));

  int in_ints[10];
  r.read((char*)&in_ints, sizeof(in_ints));

  for(i = 0;i < 10;i++) {
    cout << in_ints[i] << " ";
  }
  cout << endl;

  return 0;
}

现在,写入部分似乎成功了,例如运行 32 位长的 od 命令(我的系统是 32 位)将显示正确的序列,包括十六进制转储。

然而,阅读时,我得到了不应该发生的随机序列和负整数(它被分割了,而且大部分是零,因为我的整数很小,符号位不应该打开。)

你知道为什么我的 read 方法无法正常工作吗,而它实际上与我的 write 方法相反?

【问题讨论】:

  • 请贴一段完整的代码。
  • 这是您的实际代码吗?如果是这样,您可能想在使用读取流之前尝试关闭或至少刷新写入流。
  • 抱歉,我已经发布了整个代码。让我尝试刷新流。
  • 啊,我缺乏完整的 C++ 知识。如果您可以将其发布为回复 Sven,我可以接受。它有效。
  • 你不知道对read的调用是否成功。始终检查返回值。

标签: c++ binary ifstream integer


【解决方案1】:

r.read 之前尝试w.flush()w.close()。问题是当您编写它时通常会缓冲文本并且不会将其保存在文件中。所以r.read 的文件中没有任何内容。

【讨论】:

    【解决方案2】:

    这段代码:

    #include <iostream>
    #include <fstream>
    using namespace std;
    
    int main() {
        {
            ofstream w( "foo.txt" );
            int ints[10] = {0,1,2,3,4,5,6,8,9};
            w.write((char*)&ints, sizeof(ints));
        }
        {
            ifstream r( "foo.txt" );
            int in_ints[10];
            r.read((char*)&in_ints, sizeof(in_ints));
            for( int i = 0; i < 10; i++) {
                cout << in_ints[i] << " ";
            }
        }
    }
    

    打印:

    0 1 2 3 4 5 6 8 9 0

    请注意,您的初始化中缺少一些数字。

    【讨论】:

    • 是的,+1 来自我。尽可能晚地定义变量(想想 YAGNI),并且尽可能地本地化。
    • 实际上是一个很好的例子,我已经尝试过在 C++ 中使用范围运算符,也许这可能是一种方法。我想知道依靠超出范围来调用解构器是否是一种好方法,因为我可能稍后会更改它并忘记添加 .close()。
    【解决方案3】:

    写入文件的数据不一定对其他流可见(在 是否相同的过程)直到文件关闭或至少刷新。 如果在您启动程序之前文件"foo.bin" 不存在, 打开它进行阅读将失败(因此所有进一步的使用都将是 无操作)。你的程序违反了最基本的规则之一 编程:如果任何事情都可能失败,请始终检查它以前没有 继续。您不检查任何 IO 的结果。

    我还可以补充一点,以这种方式读写数据非常非常 脆弱,通常只能保证在相同的范围内工作 进程——甚至使用不同版本的编译器重新编译 或不同的编译器选项可能会导致数据表示 更改,结果您将无法读取写入的数据 早些时候。在int的数组的情况下,当然,这是高度 只要您不更改机器架构,就不太可能。但在 一般来说,如果您将来需要重新读取数据,这是一个 技术最好避免。 ((char*)reinterpret_cast,并且作为 我们知道,reinterpret_cast 是一个非常强烈的信号,表明存在 可移植性问题。)

    【讨论】:

      猜你喜欢
      • 2019-05-16
      • 2015-11-11
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-12
      • 1970-01-01
      相关资源
      最近更新 更多