Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 在程序运行时读取fprintf_C_String_Fopen_Printf_Formatted - Fatal编程技术网

C 在程序运行时读取fprintf

C 在程序运行时读取fprintf,c,string,fopen,printf,formatted,C,String,Fopen,Printf,Formatted,所以我在写一个用C语言编写的程序,它应该永远运行(客户机-服务器的东西),我在写一个日志。我正在使用fopen和fprintf来写入文件。我的问题是,既然程序被认为是永远运行的,那么我真的没有什么地方可以放置fclose。当我按Ctrl+C停止进程时,日志文件什么也不显示?我想使用fprintf,因为它允许我格式化字符串,有没有办法在仍有格式化字符串的情况下记录输出?每次您想写日志消息时,以附加模式打开文件,将文本打印到文件末尾,然后关闭它。每次您想写日志消息时,在追加模式下打开文件,将文本打印

所以我在写一个用C语言编写的程序,它应该永远运行(客户机-服务器的东西),我在写一个日志。我正在使用
fopen
fprintf
来写入文件。我的问题是,既然程序被认为是永远运行的,那么我真的没有什么地方可以放置
fclose
。当我按Ctrl+C停止进程时,日志文件什么也不显示?我想使用
fprintf
,因为它允许我格式化字符串,有没有办法在仍有格式化字符串的情况下记录输出?

每次您想写日志消息时,以附加模式打开文件,将文本打印到文件末尾,然后关闭它。

每次您想写日志消息时,在追加模式下打开文件,将文本打印到文件末尾,然后关闭文件。

发生的情况是输出正在被缓冲,当程序被终止时,缓冲区永远不会刷新到磁盘。您可以定期刷新缓冲区(fflush),也可以尝试捕获kill信号。具体来说,Control+C发送SIGINT信号,因此您需要为此注册一个处理程序

至于最小化潜在的缓冲区损失,我可能会使用这两种策略


编辑:正如Adam所说,您也可以在必要时打开和关闭文件,但根据您的写入频率,您可能希望保持文件打开,在这种情况下,我的答案将适用。

发生的是,输出正在被缓冲,当程序被终止时,缓冲区永远不会刷新到磁盘。您可以定期刷新缓冲区(fflush),也可以尝试捕获kill信号。具体来说,Control+C发送SIGINT信号,因此您需要为此注册一个处理程序

至于最小化潜在的缓冲区损失,我可能会使用这两种策略

编辑:正如Adam所说,您也可以在必要时打开和关闭文件,但根据您编写文件的频率,您可能希望保持文件打开,在这种情况下,我的答案将适用。

setbuf()、setvbuf()或fflush(),-和trap
SIGINT
或任何与您的系统相关的内容


#包括
#在本例中包括/*for sleep()*/
内部主(空)
{
文件*fh;
char*fn=“main.log”;
int i;
如果((fh=fopen(fn,“w”))==NULL){
fprintf(标准,
“无法打开文件%s\n”,fn);
返回1;
}
setbuf(fh,NULL);/*完全关闭缓冲*/
对于(i=1;;++i){
fprintf(fh,“%d正常”,i);
如果(!(i%120))
fprintf(fh,“\n”);
睡眠(1);
}
fclose(fh);
返回0;
}
在其他控制台中:

$tail-f main.log

收益率: 1正常2正常3正常4正常5正常6正常

或者,当您想刷新写入缓冲区时,可以使用fflush(fh)

:>


int setvbuf(文件*流、字符*buf、int模式、大小)
控制流的缓冲。模式为_IOFBF表示完全缓冲,_IOLBF表示行缓冲,_IOLBF表示无缓冲。非空buf指定要使用的缓冲区大小;否则,将分配一个缓冲区。错误时返回非零调用必须在流上的任何其他操作之前进行


void setbuf(文件*流,字符*buf)
控制流的缓冲。对于null buf,关闭缓冲,否则相当于(void)setvbuf(stream,buf,_IOFBF,BUFSIZ)


intfflush(文件*流)
刷新流,成功时返回零,错误时返回EOF。输入流的效果未定义。fflush(NULL)刷新所有输出流。

SIGINT
或任何与您的系统相关的内容


#包括
#在本例中包括/*for sleep()*/
内部主(空)
{
文件*fh;
char*fn=“main.log”;
int i;
如果((fh=fopen(fn,“w”))==NULL){
fprintf(标准,
“无法打开文件%s\n”,fn);
返回1;
}
setbuf(fh,NULL);/*完全关闭缓冲*/
对于(i=1;;++i){
fprintf(fh,“%d正常”,i);
如果(!(i%120))
fprintf(fh,“\n”);
睡眠(1);
}
fclose(fh);
返回0;
}
在其他控制台中:

$tail-f main.log

收益率: 1正常2正常3正常4正常5正常6正常

或者,当您想刷新写入缓冲区时,可以使用fflush(fh)

:>


int setvbuf(文件*流、字符*buf、int模式、大小)
控制流的缓冲。模式为_IOFBF表示完全缓冲,_IOLBF表示行缓冲,_IOLBF表示无缓冲。非空buf指定要使用的缓冲区大小;否则,将分配一个缓冲区。错误时返回非零调用必须在流上的任何其他操作之前进行


void setbuf(文件*流,字符*buf)
控制流的缓冲。对于null buf,关闭缓冲,否则相当于(void)setvbuf(stream,buf,_IOFBF,BUFSIZ)


intfflush(文件*流)

刷新流,成功时返回零,错误时返回EOF。输入流的效果未定义。fflush(NULL)刷新所有输出流。

我同意科尔宾的回答,但您问是否有其他方法获得格式化输出

有:您可以将sprintf()用于字符缓冲区,然后使用无缓冲
open/write/close
I/O


但是,不要那样做。继续使用fopen()和co,并捕捉信号。

我同意科尔宾的答案,但你问是否有其他方法获得格式化输出

有:您可以将sprintf()用于字符缓冲区,然后使用无缓冲
open/write/close
I/O

但是,不要害怕
#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;
}