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

如果我的程序通过CTRL-C终止,为什么使用fprintf输出的字符串最终不会写入输出文件?,c,file-io,printf,C,File Io,Printf,为什么fprintf在以下示例程序中给出不同的结果 例1: 如果我使用CTRL+C终止这个程序,我会得到一个名为filename的空文件 然而,使用 例2: 如果我使用CTRL+C终止这个程序,我会得到一个名为filename的文件,它包含许多带有字符串asdas的行 为什么在第一个示例中字符串没有写入文件,而在第二个示例中字符串被写入文件?在第二个示例中,有足够的调用将内部缓冲区刷新到磁盘 在第一个程序中,如果在while循环之前加上a,字符串将写入文件 #include <stdio.

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

例1: 如果我使用CTRL+C终止这个程序,我会得到一个名为
filename
的空文件

然而,使用

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


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

在第二个示例中,有足够的调用将内部缓冲区刷新到磁盘

在第一个程序中,如果在
while
循环之前加上a,字符串将写入文件

#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;
}
#包括
内部主(空){
文件*f=fopen(“文件名”,“w”);
如果(!f){
perror(“无法打开“文件名”进行写入”);
退出(退出失败);
}
fprintf(f,“asdas\n”);
fprintf(f,“asdas\n”);
如果(f)!=0){
perror(“冲洗输出失败”);
退出(退出失败);
}
而(1){}
返回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 C:\…\Temp>cl file.C 针对x64的Microsoft(R)C/C++优化编译器版本18.00.31101 ... /输出:file.exe C:\…\Temp>文件 ^C C:\…\Temp>键入文件名 阿斯达斯 阿斯达斯 请记住:

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

如本文所述,这确实是内部缓冲区中数据缓冲的问题。在第一种情况下,您需要手动刷新以将数据实际写入文件

#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;
}
然而,FWIW,我只想在这里添加,您看到这种行为是因为程序被一个信号(由CTRL+C生成)异常终止

如果您的程序已经结束(例如,在一个足够大但受控的
while()
循环之后调用),那么这两种情况将显示相同的行为,就像在该场景中一样,所有打开的流都将自动刷新

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


缓冲?第一个没有写入足够的数据以溢出缓冲区并触发刷新,而第二个没有?尝试在第二个fprintf之后添加一个fflush(),看看这是否有区别。@iharob否。
char name[128]={“filename”}没有问题和肯定不是字符串文本的数组
在最后一个
fprintf()
将解决问题后,您还可以添加
fclose(f)以在写入文件后重新分配资源。并检查从
fopen()
返回的指针是否为
NULL
,因为例如,如果您没有写入权限,您的程序将调用未定义的行为,因为
NULL
指针取消引用。因此,这是因为数据处于缓冲区中,未放入文件,需要使用fflush(f);把它放进文件,谢谢!您需要检查
fflush()
fclose()
中的返回值,因为无法保证缓冲数据能够被实际写入。@SinanÜnür感谢您的审阅。:-) 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