18

私が次のようなことをした場合:

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

unsigned int data;

file >> data;

私のストリームは常にを設定しfailbit、は初期化されdataないままになります。charただし、またはの代わりに読んだ場合unsigned char、ストリームは正常です。 perror()「結果が大きすぎる」と言っています。

私がグーグルで見た唯一のことはoperator>>、バイナリデータには使用すべきではないという提案でした(prefer read())が、演算子はよりクリーンで使いやすいと思います-そしてそれはすべてをキャストする必要はありません。

誰かがこの問題を説明できますか?

4

2 に答える 2

15

iostream抽出演算子(>>)は、バイナリデータではなく、空白で区切られた数値文字列を解釈しようとします。符号なし整数をバイナリ形式でエンコードするには、さまざまな方法があります(たとえば、リトルエンディアンのバイト順序での32ビット2の補数表現)。そのため、このようなバイナリバッファを操作するには、読み取り/書き込み関数を使用する必要があります。

ただし、挿入演算子と抽出演算子を使用して、任意の形式でバイナリデータをシリアル化するための独自のクラスを実装することを妨げるものは何もありません。このようなクラスは、ifstreamオブジェクトの読み取り関数を内部的に使用する可能性があります。あるいは、ブーストシリアル化ライブラリがすでに必要なものを正確に保持している場合があります。

于 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に格納します。

残念ながら、現在の設計では、ケース2のエラーが報告されています。おそらくこれはC++22で実現できます。

于 2016-04-13T13:51:15.583 に答える