【问题标题】:buffering behaviour of stdout in cc中标准输出的缓冲行为
【发布时间】:2012-07-05 13:45:55
【问题描述】:

当我运行第一个代码并立即按 ctrl-c 时,不会有45 写入文件。但是当我运行第二个代码时,我确实得到了45

我不明白为什么在下面的代码中会发生这种行为?如果stdout 是行缓冲的,我输入字符后不应该输出吗?我错过了什么?

第一个代码:

#include<stdio.h>
#include<stdlib.h>
int main()
{
   FILE *fp=stdout;
   fp=fopen("myfile","w");
   fprintf(fp,"%d",45);
   getchar();
  // return 0;

}

第二个代码:

#include<stdio.h>
#include<stdlib.h>
int main()
{
   FILE *fp=stdout;
   fprintf(fp,"%d",45);
   getchar();
  // return 0;

}

PS:我用的是GCC,平台是Linux。

【问题讨论】:

    标签: c stdio output-buffering


    【解决方案1】:

    我认为getchar 与您在第一个代码中观察到的缓冲没有任何关系。如果您不按任何字符并等待一段时间(即留在getchar() 内),您很可能会看到一个空文件。无论您是否使用getcharsleepwhile(1) 停止了程序,都会发生这种情况。

    现在你按下Ctrl-C,你的程序没有注册处理程序,因此你的程序突然终止。 是否在程序突然终止时刷新缓冲区/流由实现定义。在此处阅读全文

    Why is data not being flushed to file on process exit?

    例如,在我的系统(Windows 7,内部使用 gcc 和 mingw 框架的代码块)上,我可以看到 45 确实被刷新到文件中,而不管使用 getchar 或当我突然终止它时的任何东西。即在我的系统上,实现是在程序突然终止时将数据刷新到文件中。

    所以,底线是,当你以非正常方式做事时会发生什么是实现定义的!

    但第二种情况确实很奇怪,getchar 似乎 正在刷新stdout 缓冲区。一旦我找到getchar 是/似乎要刷新stdout 缓冲区的确切原因,我将立即更新这一点

    【讨论】:

    • 感谢您提供的信息。但我特别想知道为什么它在第二个代码中表现得很奇怪,其中 stdout 应该是行缓冲的,但它的行为不是那样的..
    【解决方案2】:

    造成混乱的是getchar(),当它被调用时似乎正在刷新stdout

    如果您将 getchar() 替换为 sleep(10) 之类的东西,那么您 45 将不会被打印出来。

    #include<stdio.h>
    #include<unistd.h>
    #include<stdlib.h>
    int main()
    {
       FILE *fp=stdout;
       //fp=fopen("myfile","w");
       fprintf(fp,"%d",45);
       sleep(10);
       //getchar();
      // return 0;
    
    }
    

    【讨论】:

    • 不一定。 45 可能会或可能不会被打印。请看我的回答。
    【解决方案3】:

    您正在写入物理文件的第一种情况。 fopen, fclose 是缓冲 I/O 取决于实现,数据可能不会立即提交,直到缓冲区已满。调用 fclose() 将导致缓冲区写入磁盘。

    您正在写入 STDIO 的第二种情况,写入 STDIO 的数据通常会立即显示。

    【讨论】:

    • -1:写入标准输出的数据通常不会“立即”显示,而是行缓冲,就像其他文件一样。
    • STDIO 通常会立即显示。 错了,stdout 是行缓冲的。
    猜你喜欢
    • 2016-10-25
    • 2013-11-28
    • 2013-10-27
    • 1970-01-01
    • 2014-12-07
    • 1970-01-01
    • 2012-07-05
    相关资源
    最近更新 更多