чтение fprintf во время работы программы - PullRequest
0 голосов
/ 24 марта 2012

Итак, я пишу программу, которая должна работать вечно (клиент-сервер) на C, и пишу в журнал.Я использую fopen и fprintf, чтобы иметь возможность записи в файл.Моя проблема заключается в том, что, поскольку предполагается, что программа будет работать вечно, на самом деле нет смысла ставить fclose.А когда мне Ctrl + C , чтобы остановить процесс, и файл журнала, он ничего не показывает?Я хочу использовать fprintf, потому что это позволяет мне иметь отформатированные строки, есть ли способ записать мой вывод, все еще имея отформатированные строки?

Ответы [ 4 ]

4 голосов
/ 24 марта 2012

Что происходит, так это то, что вывод буферизуется, и когда программа уничтожается, буфер никогда не сбрасывается на диск.Вы можете либо периодически очищать буфер (fflush), либо пытаться захватить сигнал уничтожения.В частности, Control + C отправляет сигнал SIGINT, поэтому вам необходимо зарегистрировать обработчик для этого.

Что бы минимизировать потенциальную потерю буфера, я бы, вероятно, использовал обе стратегии.

Как я могу поймать событие ctrl-c?(C ++)

Редактировать: Как сказал Адам, вы также можете просто открывать и закрывать файл при необходимости, но в зависимости от того, как часто вы пишете, вы можете оставить файл открытым, в которомесли мой ответ будет применим.

1 голос
/ 24 марта 2012

setbuf (), setvbuf () или fflush (), - и trap SIGINT или все, что подходит для вашей системы.


То есть

#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 хорошо 2 хорошо 3 хорошо 4 хорошо 5 хорошо 6 хорошо ^ C

или fflush(fh), когда вы хотите очистить буфер записи.

stdio.h :>


int setvbuf(FILE* stream, char* buf, int mode, size_t size); Управляет буферизацией для потокового потока.режим _IOFBF для полной буферизации, _IOLBF для строковой буферизации, _IONBF для без буферизации.Non-null buf указывает буфер размера, который будет использоваться;в противном случае буфер выделяется.Возвращает ненулевое значение при ошибке. Вызов должен быть перед любой другой операцией в потоке .


void setbuf(FILE* stream, char* buf); Управляет буферизацией для потокового потока.Для null buf отключает буферизацию, иначе эквивалентно (void) setvbuf (stream, buf, _IOFBF, BUFSIZ).


int fflush(FILE* stream); Сбрасывает поток потока и возвращает ноль в случае успеха или EOF в случае ошибки.Эффект не определен для входного потока.fflush (NULL) сбрасывает все выходные потоки.

1 голос
/ 24 марта 2012

Каждый раз, когда вы хотите написать сообщение журнала, откройте файл в режиме добавления, распечатайте текст в конце файла и закройте его.

0 голосов
/ 24 марта 2012

Я бы пошел с ответом Корбина, но вы спросили, есть ли другой способ получить форматированный вывод.

Существует: вы можете использовать sprintf () в буфер символов, а затем использовать небуферизованный open/write/close I / O.

Но не делай этого. Продолжайте использовать fopen () и co., И поймайте SIGINT.

...