18

如果我执行以下操作:

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

unsigned int data;

file >> data;

我的流将始终设置failbit并且data将保持未初始化。但是,如果我读 a charor unsigned char,则流很好。 perror()告诉我“结果太大”。

我在 Google 上看到的唯一内容是一个建议,说不operator>>应该用于二进制数据(prefer read()),但我发现该运算符更清洁、更易于使用——而且它不需要强制转换所有内容。

有人可以解释这个问题吗?

4

2 回答 2

15

iostream 提取运算符 (>>)尝试解释由空格分隔的数字字符串,而不是二进制数据。有许多不同的方法可以对二进制形式的无符号整数进行编码(例如,采用 little-endian 字节顺序的 32 位2补码表示)。这就是为什么你必须使用/函数来操作这样的二进制缓冲区。

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

于 2010-11-11T06:21:06.047 回答
0

应该按照您的描述进行。然而,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中实现。

于 2016-04-13T13:51:15.583 回答