10

次の呼び出しは期待どおりの動作をしているように見えます(ストリームを閉じて、それ以上の入力を許可しないでください-ストリームで入力を待機しているものはエラーを返します)が、すべてのコンパイラ/プラットフォームで正しいことが保証されていますか?

close(fileno(stdin));
fclose(stdin);
4

3 に答える 3

27

fclose(stdin)(暗黙的または明示的に) をさらに使用するとstdin、未定義の動作が呼び出されます。これは非常に悪いことです。「入力を禁止」しません。

close(fileno(stdin))stdin現在のバッファが使い果たされた後、からの入力をさらに試行するとEBADF、 で失敗しますが、別のファイルを開くまでは失敗します。別のファイルを開くと、そのファイルは fd #0 になり、悪いことが起こります。

より堅牢なアプローチは次のとおりです。

int fd = open("/dev/null", O_WRONLY);
dup2(fd, 0);
close(fd);

いくつかのエラーチェックが追加されています。これにより、すべての読み取り (現在のバッファーが使い果たされた後) がエラーになることが保証されます。エラーではなく、単に EOF になるようにしたい場合は、O_RDONLY代わりに を使用しO_WRONLYます。

于 2011-05-08T04:23:22.390 に答える
14

fileno(FILE *)を閉じないでください。FILEはバッファリングオブジェクトです。その実装を調べてその状態に干渉することは、他のソフトウェアモジュールでの同様の誤動作に伴うすべての警告と危険を伴います。

しないでください。

AGH。真剣に。不快な。

于 2008-11-13T20:05:23.247 に答える
3

考えられるすべてのオペレーティングシステムで正しいことが保証されるものはありません。ただし、fclose(stdin)の呼び出しは、WindowsオペレーティングシステムだけでなくPOSIX準拠のオペレーティングシステムでも機能するため、現時点で一般的に使用されているほとんどすべてのものにアクセスする必要があります。

前の回答と私のコメントで述べたように、ファイルハンドルでcloseを呼び出す必要はありません。fclose()は、すべてを適切に閉じます。

于 2008-11-13T20:08:25.703 に答える