2

これが私が最初に同等であると思ったコードの2つのスニペットです:

{
    std::ifstream stream("test.bin", std::ios_base::in | std::ios_base::binary);
    unsigned char count = 128;
    unsigned char read = 0;
    unsigned char scanline[128];
    long long start = stream.tellg();
    while (count--) {
        stream >> scanline[read++]; // <---- This is the only line which differs
    }
    long long end = stream.tellg();
    std::cout << end - start << "\n";
}

{
    std::ifstream stream("test.bin", std::ios_base::in | std::ios_base::binary);
    unsigned char count = 128;
    unsigned char read = 0;
    unsigned char scanline[128];
    long long start = stream.tellg();
    while (count--) {
        stream.read((char*)&scanline[read++], 1); // <---- This is the only line which differs
    }
    long long end = stream.tellg();
    std::cout << end - start << "\n";
}

私の問題は、最初のバージョンが153(おそらく入力データに依存)を出力し、2番目のバージョンが128(私が期待したもの)を出力することです。これは、最初のバージョンでデータが抽出される方法と関係があるはずですが、なぜそれが機能しないのか理解できません。それは単に呼び出すべきではありません:

istream& operator>> (istream& is, unsigned char& ch);

毎回fileposを1バイト移動しますか?

4

2 に答える 2

10

operator>>(たとえばここで)の説明を読むと、空白に再び当たるまで、読み取る前に空白をスキップすることがわかります。空白はスペース(0x20)だけでなく、タブ(0x09)や改行(0x0a)のようなものでもあります。

したがって、バイナリデータにテキストファイルの空白と見なされるバイトが含まれている場合、はoperator>>それらを読み取りますが保存しません。これにより、によって報告される数値が歪められtellgます。

于 2012-05-29T07:49:47.223 に答える
4

operator>>ストリームをバイナリで開くときにを使用するのは良い考えではありません。
あなたの場合、ストリームにある種の空白文字(0x20など)があると思います。それらも読み取られる修飾子を
使用できます。skipws

于 2012-05-29T07:50:44.480 に答える