【问题标题】:Why can't I read fstream's binary data with operator>>?为什么我不能用 operator>> 读取 fstream 的二进制数据?
【发布时间】:2011-05-08 07:13:12
【问题描述】:

如果我执行以下操作:

ifstream file;
file.open("somefile", ios::binary);

unsigned int data;

file >> data;

我的流将始终设置failbit,而data 将保持未初始化状态。但是,如果我改为阅读charunsigned char,则该流很好。 perror() 告诉我“结果太大”。

我在 Google 上看到的唯一内容是一个建议,说 operator>> 不应该用于二进制数据(更喜欢 read()),但我发现该运算符更简洁且更易于使用 - 它并没有'不需要铸造所有东西。

谁能解释一下这个问题?

【问题讨论】:

    标签: c++ binary stream fstream


    【解决方案1】:

    iostream extraction operator (>>) 尝试解释由空格分隔的数字字符串,而不是二进制数据。有许多不同的方法可以对二进制形式的无符号整数进行编码(例如,little-endian byte order 中的 32 位 2's complement representation)。这就是为什么您必须使用read/write 函数来操作此类二进制缓冲区的原因。

    但是,没有什么能阻止您实现自己的类,以便使用插入和提取运算符以您希望的任何形式序列化二进制数据。这样的类可能会在内部使用 ifstream 对象的读取函数。或者,boost serialization library 可能已经包含您想要的内容。

    【讨论】:

      【解决方案2】:

      应该按照您的描述进行。然而,C++ 标准设计者并不是很优雅。事实上,C++的设计有很多缺陷,甚至C++11和C++14也有很多缺陷。

      理想的 C++ 设计应该是:

      1.对于文本文件:

      ifstream fin_txt("input.txt");
      int i;
      float j;
      double k;
      fin_txt >> i >> j >> k;
      

      这将读入3个字符串并解析为整数、浮点数和双精度,并分别存储到i、j和k中。

      2.对于二进制文件:

      ifstream fin_txt("input.bin", ios::binary);
      int i;
      float j;
      double k;
      fin_txt >> i >> j >> k;
      

      这会读入4/8字节(取决于int是32位还是64位)、4字节和8字节二进制数据,分别存入i、j、k。

      很遗憾,目前的设计是针对Case 2报错的。或许这可以在C++22中实现。

      【讨论】:

      • 您在回答中得到了这种方式的原因:“取决于 int 是 32 位还是 64 位”。目前,使用<iostreams> 的代码是可移植的,您的建议不是。
      • 致@Caleth,好吧,正如我所说,这是标准 C++ 中的另一个设计缺陷,它应该区分 int32 和 int64 而不仅仅是 int,它可以是 32 位或 64 位,将来可能是 128 位。 int 的字段大小确定性与其他的不同(char=8-bits, long=32-bits, long long=64-bits, float=32-bits, double=64-bits)。为了解决这个问题,我们可以简单地分别定义 int32 和 int64,如果给二进制文件一个字段大小非确定性类型,即 fin_txt >> i; 则会抛出运行时错误。 // 抛出错误,fin_txt >> (int32)i; // 正确编译
      • 这不是ios::binary(和ios::text)的用途。一些平台在“文本模式”和“二进制模式”之间区分它们如何呈现带有行结束字符的文件。 ios 标志处理。
      • @Caleth 那么可能有一个带有操作符的文本流>>和>作为二进制写入完成
      猜你喜欢
      • 2015-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多