だから私はCで永遠に実行されると思われるプログラム(クライアントサーバーのもの)を書いていて、ログに書いています。ファイルに書き込めるようにfopen
andを使用しています。fprintf
私の問題は、プログラムが永遠に実行されると想定されているため、fclose
. そして、プロセスとCtrlログCファイルを停止すると、何も表示されませんか? 書式設定された文字列を使用できるため、使用したいのですfprintf
が、書式設定された文字列を保持しながら出力をログに記録する方法はありますか?
4 に答える
何が起こっているかというと、出力がバッファリングされており、プログラムが強制終了されたときに、バッファがディスクにフラッシュされることはありません。バッファを定期的にフラッシュする (fflush) か、kill シグナルのキャプチャを試みることができます。具体的には、Control + C は SIGINT シグナルを送信するため、そのハンドラーを登録する必要があります。
潜在的なバッファー損失を最小限に抑えるために、おそらく両方の戦略を使用します。
ctrl-c イベントをキャッチするにはどうすればよいですか? (C++)
編集:アダムが言ったように、必要に応じてファイルを開いたり閉じたりすることもできますが、書き込みの頻度によっては、ファイルを開いたままにしておくこともできます。その場合、私の答えが適用されます。
ログ メッセージを書き込むたびに、ファイルを追加モードで開き、テキストをファイルの最後まで出力してから閉じます。
setbuf()、setvbuf()、または fflush()、および trapSIGINT
またはシステムに関連する適切なもの。
いえ
#include <stdio.h>
#include <unistd.h> /* for sleep() in this example */
int main(void)
{
FILE *fh;
char *fn = "main.log";
int i;
if ((fh = fopen(fn, "w")) == NULL) {
fprintf(stderr,
"Unable to open file %s\n", fn);
return 1;
}
setbuf(fh, NULL); /* Turns buffering completely off */
for (i = 1; ; ++i) {
fprintf(fh, "%d ok ", i);
if (!(i%120))
fprintf(fh, "\n");
sleep(1);
}
fclose(fh);
return 0;
}
他のコンソールで:
$ tail -f main.log 生成
: 1 OK 2 OK 3 OK 4 OK 5 OK 6 OK ^C
またはfflush(fh)
、書き込みバッファをフラッシュしたい場合。
stdio.h :>
int setvbuf(FILE* stream, char* buf, int mode, size_t size);
ストリーム stream のバッファリングを制御します。mode は、フル バッファリングの場合は _IOFBF、ライン バッファリングの場合は _IOLBF、バッファリングなしの場合は _IONBF です。null 以外の buf は、使用するサイズ size のバッファーを指定します。それ以外の場合は、バッファーが割り当てられます。エラー時にゼロ以外を返します。呼び出しは、ストリームの他の操作よりも前に行う必要があります。
void setbuf(FILE* stream, char* buf);
ストリーム stream のバッファリングを制御します。null buf の場合、バッファリングをオフにします。それ以外の場合は、(void)setvbuf(stream, buf, _IOFBF, BUFSIZ) と同等です。
int fflush(FILE* stream);
ストリーム stream をフラッシュし、成功の場合は 0 を返し、エラーの場合は EOF を返します。入力ストリームの影響は未定義です。fflush(NULL) は、すべての出力ストリームをフラッシュします。
私はコービンの答えに行きますが、フォーマットされた出力を取得する別の方法があるかどうか尋ねました。
あります: sprintf() を char バッファに使用してから、バッファリングされていないopen/write/close
I/O を使用できます。
しかし、そうしないでください。fopen() などを使用し続け、SIGINT をキャッチします。