15

fopenQ:モードを使用して"r+"、特定の文字列を読み取り、変更された文字列を書き戻すことによって、ファイルを所定の位置で更新しようとしていますが、機能しません。

A:書き込む前に必ず呼び出してfseekください。これは、上書きしようとしている文字列の先頭に戻るためと、読み取り/書き込み「+」モードでの読み取りと書き込みの間に常にfseek orが必要なためです。fflush

私の質問は、読み取り/書き込み「+」モードでの読み取りと書き込みの間になぜ fseekまたは常に必要なのかということです。AndrewKoenigのCTrapsand Pitfallsfflush (1989)のセクション5.2は 、下位互換性の問題が原因であると述べています。誰かが詳細に説明できますか?

4

3 に答える 3

16

ライブラリは、入力および出力操作をバッファリングします。その機能のパラメータを確認してくださいsetvbuf()_IOFBF_IOLBF

fseek()または、ライブラリにバッファリングされた操作をコミットするようにfflush() 要求します。

この規格では、ライブラリにいくつかのショートカットを許可するために、シークまたはフラッシュ操作が必須であると指定されています。そうしないと、すべてのI / O操作について、libは前の操作も読み取り操作(または書き込み操作)であるかどうかを確認し、I/Oの「方向」が変更された場合はそれ自体でフラッシュをトリガーする必要があります。仕様をそのまま使用すると、ライブラリは、クライアントがI/O方向を変更する前にシーク/フラッシュを実行したと想定する場合があります。

于 2009-11-11T08:43:14.133 に答える
5

それはOS/ライブラリコードをより単純に保つからです。ファイルストリームには個別の読み取りバッファと書き込みバッファがある場合があり、それらが常に同期されていることを確認するには、追加の作業が必要になります。これは、必要のないときにパフォーマンスを犠牲にすることになります。

したがって、代わりに、プログラマーは必要なときにこれを明示的に行う必要があります。

于 2009-11-11T08:44:16.900 に答える
5

(C89)標準ライブラリのさまざまな機能がそのままである理由、特に標準I / Oライブラリの一部がそのままである理由についての洞察については、Plaugerの「標準Cライブラリ」をお読みください。1つの理由は、Cが非常に多様なシステムと多様なメディアで実行されることです。テープなどのデバイスは、あなたが考えているディスクドライブとは多少異なる方法で処理する必要があるかもしれません。また、Unixでは、「tty」デバイス(キーボードとマウスを画面に接続する)を考えてみてください。3つのまったく異なるハードウェアです。それらの間の調整は十分に注意が必要です。標準のルールはそれを容易にします。


標準ではこれが義務付けられていることに注意してください。これはC11標準、ISO / IEC 9899:2011からのものですが、以前のエディションと同様の表現でした。

§7.21.5.3fopen関数

¶7ファイルが更新モード(上記のモード引数値のリストの2番目または3番目の文字として「+」)で開かれると、入力と出力の両方が関連するストリームで実行される場合があります。ただし、fflush関数またはファイルポジショニング関数(、、、fseekまたは fsetposrewindへの呼び出しが介在しない限り、出力の直後に入力が続くことはありません。また、ファイルポジショニング関数への呼び出しが介在することなく、入力の直後に出力が続くことはありません。入力操作でファイルの終わりが発生しました。一部の実装では、更新モードでテキストファイルを開く(または作成する)と、代わりにバイナリストリームを開く(または作成する)場合があります。

于 2009-11-11T08:47:04.110 に答える