web-dev-qa-db-ja.com

ファイルの終わりに達した後、ifstreamオブジェクトを巻き戻します

数文字(10文字とする)のテキストファイルがある場合、そこから1000文字を読み取ることができます。

char *buf = new char[1000];
ifstream in("in.txt");
in.read(buf, 1000);

もちろん、これは eofbit フラグ(および failbit も)を設定しますが、必要な文字を取得できます。

ここで、ファイルをもう一度(最初から)読み取りたいとします。

in.seekg(0);        // Sets input position indicator. 
in.read(buf, 100);  // Try to read again.

これは機能しません。

int count = in.gcount()  // Charecters readed from input.

count == 0。つまり、まったく何も読み取っていません。

したがって、質問:ファイルの終わりに達した後、ファイルを巻き戻すにはどうすればよいですか?

16
Raydel Miranda

解決

seekgを呼び出す前にifstreamの状態を消去するには、 clear を使用します。 後で状態を知る必要がないかどうか、最初に確認してください。

in.clear();
in.seekg(0);

説明

seekg 入力位置を設定しますが、clear状態ビットを設定しません failbit なので、- ifstream インスタンスは、「何かが間違っている」と「考えています」。

標準仕様から:

std :: basic_istream :: seekgnformattedInputFunction として動作しますが、gcount()は影響を受けません。

nformattedInputFunction で読み取ることができます:

次の標準ライブラリ関数はUnformattedInputFunctionsです。

basic_istream :: seekg、ただしは最初にeofbitをクリアし、 gcountを変更する

質問の例で、seekgの前後の状態を出力すると、次のようになります。

cout << "State before seekg: " << in.rdstate() << endl;   // Prints 3 (11 in binary) failbit and eofbit activated.
in.seekg(0);
cout << "State after seekg: " << in.rdstate() << endl;    // Prints 2 (10 in binary) just failbit activated.

それが理由です!!

seekgは failbit をクリアしません。また、実装上の理由から、そのようなビットがアクティブになっていると動作しません。

私の推測

failbit がアクティブなときにseegkが機能しないのはなぜですか?

これは、ストリームがファイルの最後に達したときにこのビットがアクティブになるだけではないという事実に関係しています。また、failbitがアクティブになった後、gseekを使用するとエラーが発生しやすくなったり、未定義の動作が発生したりする場合があります。

43
Raydel Miranda