You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

写入txt文件时,Ctrl+d与Ctrl+c终止程序的差异解析

问题:Ctrl+C终止程序时文件无内容,Ctrl+D却正常?

测试代码

#include <stdio.h>

int main(void)
{
   FILE *cfPtr = NULL;

   if ( (cfPtr = fopen("clients.txt","w")) == NULL ){
        puts("File could not be opened");
   }else{
        puts("Enter the account, name, and balance");
        puts("Enter EOF to end input.");
        printf("%s", "? ");
        int account = 0;
        char name[30] = "";
        double balance = 0.0;
        scanf("%d%29s%lf",&account,name,&balance);
        
        while (!feof(stdin)){
            fprintf(cfPtr,"%d %s %.2f\n",account,name,balance);
            printf("%s", "? ");
            scanf("%d%29s%lf",&account,name,&balance);
        }

        fclose(cfPtr);
   }
}

测试输入

Enter the account, name, and balance
Enter EOF to end input.
? 100 Jones 24.98
? 200 Doe 345.67
? 300 White 0.00
? 400 Stone -42.16
? 500 Rich 224.62

原因与解释

核心问题:标准库的缓冲区机制

C语言标准库的文件I/O默认使用缓冲模式,fprintf写入的数据并不会直接写到磁盘文件,而是先暂存到内存中的缓冲区里。只有满足以下条件之一时,缓冲区的内容才会同步到磁盘:

  • 缓冲区被写满;
  • 调用fflush()函数强制刷新缓冲区;
  • 调用fclose()关闭文件(关闭时会自动触发缓冲区刷新)。

两种终止方式的差异

  • Ctrl+D终止:Ctrl+D是向标准输入(stdin)发送EOF信号,程序会正常执行完while循环,最后走到fclose(cfPtr)语句。fclose会自动把缓冲区里的所有数据写入磁盘,所以clients.txt里能看到完整的输入内容。
  • Ctrl+C终止:Ctrl+C是向进程发送SIGINT中断信号,程序会被立即终止,根本没机会执行fclose,缓冲区里暂存的数据还没来得及同步到磁盘,最终文件就是空的。

可选解决办法

如果需要在异常终止时也保留写入的数据,可以试试这两种方案:

  • 每次调用fprintf后,立刻调用fflush(cfPtr)强制刷新缓冲区,这样数据会实时写入磁盘,但频繁刷新会降低程序性能;
  • 给SIGINT信号注册一个处理函数,在收到中断信号时先执行fclose(cfPtr)再退出程序,确保缓冲区数据被写入。示例代码片段:
#include <signal.h>

FILE *cfPtr; // 把文件指针设为全局变量,方便信号处理函数访问

void sigint_handler(int sig) {
    if (cfPtr != NULL) {
        fclose(cfPtr);
    }
    exit(0);
}

// 在main函数开头注册信号处理函数
signal(SIGINT, sigint_handler);

内容的提问来源于stack exchange,提问作者CroCo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 07:16:10