15

最近、fstream :: eof()を使用することで問題が発生しました。私はここから次の行を読みました:

関数eof()は、関連付けられた入力ファイルの終わりに達した場合はtrueを返し、それ以外の場合はfalseを返します。

そして(誤って)これは、fstream :: read()を使用してファイルの終わりを超えて読み取った場合、関数eof()が教えてくれることを意味すると想定していました。だから私はこのようなことをしました(非常に一般化されています):

for(int i = 0; i < max && !file.eof(); i++)
{
     file.read(mything, sizeof(mything));
}

この問題は、上記のリンク先のページで後で説明されていることが原因で発生しました(誤解を招く最初の段落のおかげで、最初は読むことができませんでした)。

逆に、最後のトークンの後に空白がある場合、ストリームはEOF状態にはなりませんが、別のトークンを読み取ろうとすると失敗します。したがって、EOFフラグは、EOFまですべてのストリームコンテンツを読み取ることを目的としたループのテストとして使用することはできません。代わりに、読み取りを試みた後、失敗状態をチェックする必要があります。

そこで変更を加えたところ、ループはfile.eof()ではなくfile.fail()をチェックし、eof()がどのように機能するかを理解しました。私の質問は、なぜそれがそのように機能するのかということです。これが望ましい状況はありますか?EOFを通過すると、EOFを通過し、eof()はtrueを返すはずです。

更新 回答ありがとうございます、私はそれを持っていると思います。私が実行している操作はread()だけで、すぐにfail()をチェックするので、大丈夫だと思います。さて、私の質問は、eof()を何に使用するのかということです。

4

2 に答える 2

17

このようにしてEOF、ファイルのサイズを知らなくても検出できるためです。単に読み取りを試みるだけで、読み取りが短い場合(エラーではない場合)、ファイルの終わりに到達しています。

これは、ファイルIOが通常呼び出すシステムコールの機能を反映してreadいます(win32のものが呼び出す場合がありますReadFileが、機能は類似していると思います)。

readマンページの「RETURNVALUE」セクションから(強調を追加):

成功すると、読み取られたバイト数が返され(ゼロはファイルの終わりを示します)、ファイルの位置はこの数だけ進められます。この数が要求されたバイト数よりも小さい場合はエラーではありません。これは、たとえば、現在実際に使用可能なバイト数が少ないため(ファイルの終わりに近かったため、パイプまたは端末から読み取っているため)、またはread()が信号。エラーの場合、-1が返され、errnoが適切に設定されます。この場合、ファイルの位置(存在する場合)が変更されるかどうかは指定されません。

ところで:あなたが望むものを書くための良い方法は次のようになります:

T something;
while(file.read(something, sizeof(something))) {
    // process your 'something'
}

これは、file.read(iostreamの多くのメンバーと同様に)iostream自体への参照を返すために機能します。これらはすべて、ストリームの状態をテストできるように演算子がオーバーロードされています。から読み取るのと同様にstd::cinwhile(std::cin >> x) { ... }も機能します。

編集:同じ理由で、テストと失敗が同じように間違っている可能性があることを知っておく必要があります。リンク先のページから、前の操作が失敗したfail()場合に戻ります。つまり、テストする前に、読み取りまたはその他の関連する操作を実行する必要があります。

于 2009-06-24T17:15:21.300 に答える
0
int n;
std::cin >> n >> std::stripws;

この問題を修正します。その時点で、.good()または.eof()のいずれかを使用できます。不良ディスクブロックがある場合、.good()がそれを検出するため、.good()を使用するのが好きです。しかし、それは私です。.eof()は追加されません。また、.fail()を追加する必要があります|| 。悪い()。

空白を食べることの問題についてのいくつかのハードな研究の後で、私はちょうどこれを見つけました。私はiostreamとifstreamにECOを提案するつもりでしたが、見よ、それはすでに行われています。:-D

于 2012-04-29T11:53:46.357 に答える