1

VS 2005では、次のようなコードがあります。

ifs.open("foo");
while (!ifs.eof())
{
    ifs.read(&bar,sizeof(bar));
    loc = ifs.tellg();
    loc += bar.dwHeaderSize;
    // four byte boundary padding
    if ((loc % 4) != 0)
        loc += 4 - (loc % 4);
    ifs.seekg(loc,ios::beg);
}
ifs.close();

コードはVS2005では正常に機能しましたが、VS2008Expressでは失敗します。私の知る限り、VS 2008は、コードがファイルの最後をシークした後、eof()を返していません。私は何かが足りないのですか?シークの場所がファイルサイズを超えているかどうかを確認する明示的なチェックを追加して修正しましたが、ifstreamを正しく理解していることを確認したいと思います。

4

1 に答える 1

2

EOFフラグは、ファイルの終わりを超えて読み取ろうとした後にのみトリガーされます。
ファイルの終わりを読み取っuptoても、それはトリガーされません。

これが、ほとんどのコードが次のように見える理由です。

while(ifs.read(&bar,sizeof(bar)))
{
     // Do Stuff
}

read()の結果がEOFに達すると、ループに入ります。
read()の結果がEOFを超えた場合、ループは開始されません

  • 注:read()は、ファイルにゼロバイトが残っている場合にのみEOFを通過します。それ以外の場合は、ファイルの最後まで読み取ります。したがって、ファイルに何かが残っている場合は、常にループに入ります。

その理由は、読み取りの結果(戻り値)がストリームへの参照であるためです。ストリームがブールコンテキスト(ifテスト式など)で使用される場合、そのようなコンテキストで使用できるタイプに変換されます。この変換の結果は、(他のいくつかに加えて)EOFフラグをテストし、EOFがtrueの場合はfalseに相当するものを返します。

注:
この手法は、Barクラスの演算子<<をオーバーロードすると、EOFを超えずにオブジェクトに必要なものを正確に読み取る必要があるため、より適切に機能します。そうすれば、オブジェクトをファイルの最後まで正確に読み取らせることが簡単になります。readで私が心配しているのは、read()が10バイトを必要とし、ファイルに5バイトしかない場合、部分的に満たされたオブジェクトはどうなるかということです。

引き続きスタイルを使用する場合、コードは次のようになります。

ifs.open("foo");
while (!ifs.eof())
{
    ifs.read(&bar,sizeof(bar));
    if (ifs.eof())
    {    break;
    }
    // Do Stuff
}
于 2009-07-08T18:19:22.860 に答える