stdout的缓冲

来源:11-11 案例:重定向标准输入输出流

wxz123

2021-02-08

#include <stdio.h>
#include <io_utils.h>
#include <time_utils.h>
#include <locale.h>

#if defined(__APPLE__) || defined(__linux__)
#  include <unistd.h>
#elif defined(_WIN32)
#  include <io.h>
#endif

void RedirectStdout(char const *filename) {
  static int saved_stdout_no = -1;

  if (filename) {
    if(saved_stdout_no == -1) {
      saved_stdout_no = dup(fileno(stdout));
//      printf("%d\n",fileno(stdout));
//        printf("%d\n",saved_stdout_no);
    }

    //fflush(stdout);
    freopen(filename, "a", stdout);
  } else {
    if (saved_stdout_no != -1) {
      //fflush(stdout);
      dup2(saved_stdout_no, fileno(stdout));
      close(saved_stdout_no);
      saved_stdout_no = -1;
    }
  }
}

int main() {
  //freopen("output.log", "a", stdout);
//  puts("This will be written to file 'output.log'");
//  fclose(stdout);
//    puts("123");
  puts("1");
  RedirectStdout("output.log");
  puts("2");
  RedirectStdout(NULL);
  puts("3");

  RedirectStdout("output.log");
  puts("4");
  //RedirectStdout(NULL);
  //puts("end");
  return 0;
}

老师,上面的代码我把fflush(stdout)都注释掉了。
我的理解是:对于stdout如果不使用fflush(stdout),一直调用puts函数,puts中的内容会一直存在缓冲中的(假设stdout的缓冲区一直没满),一直到程序运行结束,缓冲区的内容会直接放到stdout最终时刻指向的那个位置(文件、控制台这些)。
问题:那为啥该程序运行会把1、2、3打印到控制台上,把4放到"output.log"文件中(我的预期是把1、2、3、4都放到"output.log"文件中)

写回答

1回答

bennyhuo

2021-02-09

嗯,实际上 freopen 这个函数的作用是先关闭传入的流,再用文件重新打开,所以这里的关闭理论上也会触发 flush。


//fflush(stdout); 实际上这一句可以去掉,不过加上也没什么坏处
freopen(filename, "a", stdout);

0
1
wxz123
非常感谢!
2021-02-09
共1条回复

C语言系统化精讲 重塑编程思想 打造坚实的开发基础

如果通向大牛的道路有捷径,那就是先学好C语言

2208 学习 · 853 问题

查看课程