28

ifstream を使用してバイナリ ファイルをバイト単位で読み取ろうとしました。以前に get() のような istream メソッドを使用して、バイナリ ファイルのチャンク全体を問題なく一度に読み取ったことがあります。しかし、私の現在のタスクは、バイトごとに進み、io-system のバッファリングに依存して効率化することに適しています。問題は、本来よりも数バイト早くファイルの終わりに到達したように見えることです。そこで、次のテストプログラムを書きました。

#include <iostream>
#include <fstream>

int main() {
    typedef unsigned char uint8;
    std::ifstream source("test.dat", std::ios_base::binary);
    while (source) {
        std::ios::pos_type before = source.tellg();
        uint8 x;
        source >> x;
        std::ios::pos_type after = source.tellg();
        std::cout << before << ' ' << static_cast<int>(x) << ' '
                  << after << std::endl;
    }
    return 0;
}

これにより、test.dat の内容が 1 行に 1 バイトずつダンプされ、前後のファイル位置が示されます。

案の定、ファイルに 2 バイト シーケンス 0x0D-0x0A (キャリッジ リターンとライン フィードに対応) がある場合、それらのバイトはスキップされます。

  • バイナリ モードでストリームを開きました。それは行区切りを解釈するのを妨げるべきではありませんか?
  • 抽出演算子は常にテキスト モードを使用しますか?
  • バイナリ istream からバイト単位で読み取る正しい方法は何ですか?

Windows 上の MSVC++ 2008。

4

5 に答える 5

24

>>エクストラクタはフォーマットされた入力用です。空白をスキップします(デフォルト)。単一文字のフォーマットされていない入力の 場合、 istream::get()(読み取りが失敗した場合はEOFを返すintか、[0、UCHAR_MAX]の範囲の値を返します)またはistream::get(char&)(引数に読み取った文字を入れて、に変換されるものを返します bool。読み取りは成功し、失敗した場合はfalseになります。

于 2011-04-01T15:34:19.137 に答える
5

バイト数を指定できるread()メンバー関数があります。

于 2011-04-01T12:51:55.800 に答える
4

なぜではなく、フォーマットされた抽出を使用しているのです.read()か?

于 2011-04-01T13:05:56.090 に答える
4
source.get()

あなたにシングルバイトを与えるでしょう。書式なし入力関数です。operator>> は、空白文字をスキップすることを意味する可能性がある書式設定された入力関数です。

于 2011-04-01T13:48:55.280 に答える
2

他の人が述べたように、を使用する必要がありますistream::read()。ただし、フォーマットされた抽出を使用する必要がある場合は、 を検討してstd::noskipwsください。

于 2011-04-01T14:22:04.883 に答える