如果我的程序通过CTRL-C终止,为什么使用fprintf输出的字符串最终没有被写入输出文件?

时间:2015-05-14 14:37:38

标签: c file-io printf

为什么fprintf在以下示例程序中给出不同的结果?

示例1:

int main(){
    FILE *f;
    char buf[512];
    char name[128] = {"filename"};

    f = fopen(name, "w");
    fprintf(f, "asdas\n");
    fprintf(f, "asdas\n");
    while(1){}
    return 0;
}

如果我使用 CTRL + C 终止此程序,我会得到一个名为filename文件。

然而,使用

示例2:

int main(){
    FILE *f;
    char buf[512];
    char name[128] = {"wpa_supplicant.conf"};

    f = fopen(name,"w");
    while(1){
        fprintf(f, "asdas\n");
    }
    return 0;
}

如果我使用 CTRL + C 终止此程序,我会得到一个名为filename的文件,它包含许多带有字符串asdas的行

为什么在第一个示例中字符串没有写入文件,但是在第二个示例中它们被写入文件?

2 个答案:

答案 0 :(得分:5)

在第二种情况下,有足够的fprintf调用将内部缓冲区刷新到磁盘。

使用第一个程序,如果在while循环之前放置fflush(f),则字符串将被写入文件。

#include <stdio.h>

int main(void) {
    FILE *f = fopen("filename", "w");
    if (!f) {
        perror("Failed to open 'filename' for writing");
        exit(EXIT_FAILURE);
    }

    fprintf(f, "asdas\n");
    fprintf(f, "asdas\n");

    if ( fflush(f) != 0 ) {
        perror("Flushing output failed");
        exit(EXIT_FAILURE);
    }

    while(1){}
    return 0;
}

输出:

C:\...\Temp> cl file.c                       
Microsoft (R) C/C++ Optimizing Compiler Version 18.00.31101 for x64
...
/out:file.exe                                                      

C:\...\Temp> file                            
^C                                                                 
C:\...\Temp> type filename                   
asdas                                                              
asdas

请记住:

  

成功完成后,fflush()将返回0;否则,它应设置流的错误指示符,返回EOF,并设置errno以指示错误。

答案 1 :(得分:1)

the answer by @SinanÜnür中所述,这确实是内部缓冲区中数据缓冲的问题。在第一种情况下,您需要手动刷新,以便将实际写入的数据放入文件

然而,FWIW,我只想在这里添加,你会看到这种行为,因为信号异常终止程序(由 CTRL + C 生成) 。

如果你的程序已经结束normally,(,例如,通过调用exit(),在一个足够大但受控制的while()循环之后),那么这两种情况都会表现出相同的行为,因为在这种情况下,所有开放的流都会自动刷新。

  然后,exit()函数将使用未写入的缓冲数据刷新所有打开的流并关闭所有打开的流。最后,该程序将被终止......