stdout,stdin和stderr分别是标准输出流、标准输入流和标准错误流,当一个用户进程被创建的时候,系统会自动为该进程创建这三个数据流,默认情况下这三个流是在终端上表现出来的。可以使用fprintf函数将数据打印到流中,如调用函数fprintf(stdout, "hello world\n");或者fprintf(stderr, "hello world\n");则会在终端中显示“hello world”,调用fgets(buf, 32, stdin);则表示从终端获取一行数据。

stdout和stderr的区别就是stdout是有缓存的,而stderr是没有缓存的,最直观的体现就是输出到stdout和stderr中的字符什么时候在终端中显示。对于stderr而言,输出到stderr中的字符立马会在终端中显示出来,而对于stdout而言要满足一下几个条件才会在屏幕中显示出来:

1)遇到'\n'

2)流关闭

3)用fflush函数刷新

4)缓冲区即将溢出

下面对以上情况一一举例说明,编写下列代码:

1 #include <stdio.h>
2
3 int main(int argc, const char *argv[])
4 {
5     fprintf(stdout, "hello world");
6     while(1);
7
8     return 0;
9 }

该程序执行后终端是没有打印的,因为不满足上述4种情况中的任何一种。第6行的死循环是为了避免流关闭。

将代码修改如下:

1 #include <stdio.h>
2
3 int main(int argc, const char *argv[])
4 {
5     fprintf(stdout, "hello\nworld");
6     while(1);
7
8     return 0;
9 }

在“hello”和"world"之间插入一个'\n',可以看到终端中输出了“hello”但是没有输出“world”,验证了第1种情况。

将代码修改如下:

 1 #include <stdio.h>
 2
 3 int main(int argc, const char *argv[])
 4 {
 5     fprintf(stdout, "hello world");
 6     fclose(stdout);
 7     while(1);
 8
 9     return 0;
10 }

将标准输出流关闭,可以看到输出的“hello world”,验证了第2种情况。

将代码修改如下:

 1 #include <stdio.h>
 2
 3 int main(int argc, const char *argv[])
 4 {
 5     fprintf(stdout, "hello world");
 6     fflush(stdout);
 7     while(1);
 8
 9     return 0;
10 }

刷新输出流缓冲区,可以看到输出的“hello world”,验证了第3种情况。第4种情况与流的缓存类型有关,缓存类型分为无缓冲、行缓冲和全缓冲,行缓冲的缓冲区大小为1024个字节,全缓存的缓冲区大小为4096个字节,默认情况下与文件建立的缓冲类型为全缓冲,与终端建立的缓冲类型为行缓冲。

将代码修改如下:

 1 #include <stdio.h>
 2
 3 int main(int argc, const char *argv[])
 4 {
 5     int i;
 6
 7     for (i = 0; i < 1025; i++) {
 8         fprintf(stdout, "a");
 9     }
10
11     while(1);
12
13     return 0;
14 }

终端将显示1024个‘a’(当然我没数),而将第7行的1025改为1024则终端不会显示。

可以使用setvbuf函数改变流的缓冲类型。

原型:int setvbuf(FILE *stream, char *buf, int mode, size_t size);

参数:

  stream:流指针

  buf:分配给用户的缓冲。如果设置为 NULL,该函数会自动分配一个指定大小的缓冲

  mode:缓冲类型

    _IONBUF:无缓冲

    _IOLBUF:行缓冲

    _IOFBUF:全缓冲

  size:缓冲区大小

将代码修改如下:

 1 #include <stdio.h>
 2
 3 int main(int argc, const char *argv[])
 4 {
 5     setvbuf(stdout, NULL, _IONBF, 1024);
 6     fprintf(stdout, "a");
 7
 8     while(1);
 9
10     return 0;
11 }

运行程序,在屏幕上是会显示出字符‘a'的,因为使用setvbuf将标准输出流设置成了无缓冲。

在测试时发现以下几个现象,注意标红的地方:

 1 #include <stdio.h>
 2
 3 int main(int argc, const char *argv[])
 4 {
 5     int i;
 6
 7     setvbuf(stdout, NULL, _IOLBF, 5);
 8     for (i = 0; i < 1025; i++) {
 9         fprintf(stdout, "a");
10     }
11
12     while(1);
13
14     return 0;
15 }

运行该程序有输出,而将1025改为1024则没有输出,将_IOLBF改为_IOFBF也是1024没有输出,1025有输出。

修改代码如下:

 1 #include <stdio.h>
 2
 3 int main(int argc, const char *argv[])
 4 {
 5     int i;
 6     char buf[4097];
 7
 8     setvbuf(stdout, buf, _IOLBF, 5);
 9     for (i = 0; i < 5; i++) {
10         fprintf(stdout, "a");
11     }
12
13     while(1);
14
15     return 0;
16 }

运行程序,屏幕不显示,将第9行标红的5改为6则屏幕有显示,将第8行的_IOLBF改为_IOFBF现象也是一样的。

这让我产生一种感觉:

  1)setvbuf第二个参数为NULL时,第4个参数是不起作用的。

  2)默认stdout的行缓冲和全缓冲大小都是1024个字节。

但是我记得默认的全缓冲大小为4096个字节呀。。。

转载于:https://www.cnblogs.com/Suzkfly/p/10367376.html

五、stdout,stdoin和stderr相关推荐

  1. python sys stdout_如何理解python中的sys.stdout和sys.stderr

    我有以下简单的python代码. stdout = sys.stdout stderr = sys.stderr try: # omited finally: sys.stdout = stdout ...

  2. python 中的 sys.stdin ,sys.stdout 和sys.stderr

    文档解释: File objects used by the interpreter for standard input, output and errors: stdin is used for ...

  3. stdout标准输出、stderr标准错误输出 标准输入、标准输出、标准错误输出分别被定义为0、1、2。

    $ make > compile.log 2>&1 首先将标准错误输出也重定向到标准输出中,再将标准输出重定向到 compile.log 这个文件中.这样我们就可以将所有的输出都存 ...

  4. printf,fprintf(stdout,stderr),sprintf等的使用方法及区别

    名称 描 述 例 子 stdin 标准输入 键盘 stdout 标准输出 屏幕 stderr 标准错误 屏幕 stdprn 标准打印机 LPT1端口 stdaux 标准串行设备 COM1端口 1,pr ...

  5. python stdout stderr 一起输出_Python在保留顺序的同时分别从子进程stdout和stderr读取...

    小智.. 6 写入后,进程将数据写入不同管道的顺序将丢失. 您无法判断在stderr之前是否已写入stdout. 您可以尝试在数据可用时以非阻塞方式同时从多个文件描述符中同时读取数据,但这只会最大程度 ...

  6. stdout和stderr标准输出的区别

    stderr和stdout详细解说 今天又查了一下fprintf,其中对第一个参数stderr特别感兴趣. int fprintf(FILE *stream,char *format,[argumen ...

  7. python stdout stderr 一起输出_python – 使用subprocess.Popen()时,stderr和stdout没有输出

    我正在使用 Python来自动化SVN提交,我想将SVN命令的输出写入日志文件.我有的代码可以使SVN运行,但问题是在成功提交时,子进程调用不会返回我的日志的任何输出. 当我手动运行SVN时,通过比较 ...

  8. stdin,stdout,stderr

    我们在写C程序时经常遇到printf(),fprintf(),perror(),这些东西到底有什么作用.说到这不得不提及stdin,stdout,stderr.想想,我们在用C去写文件时的操作,Fil ...

  9. stderr和stdout详细解说

    今天又查了一下fprintf,其中对第一个参数stderr特别感兴趣. int fprintf(FILE *stream,char *format,[argument]): 在此之前先区分一下:pri ...

最新文章

  1. 2022-2028年中国体育用品行业投资分析及前景预测报告(全卷)
  2. 企业级工作流解决方案(八)--微服务Tcp消息传输模型之服务端处理
  3. python判断是否有属性
  4. objc_msgSend() 使用报错解决方案
  5. 读书记:asp.net2.0电子商务开发实战
  6. JS判断IE6/IE7/IE8系列的写法
  7. vue 监听state 任意值变化、监听mutations actions
  8. mysql之delete删除记录后数据库大小不变
  9. 大数据应用智能交通有哪些意义
  10. redis命令_Redis 命令执行过程(上)
  11. oc基础-oc中之集合NSSet,NSMutableSet
  12. 全美电影票房排行(截止2010.12.19)
  13. 额~~~字符表情大全(写博客需要)
  14. 承上启下的总结+从吴军的书《态度》总结出的20条为人方法生活状态
  15. SVN服务端和客户端搭建教程
  16. Linux操作系统(笔记)
  17. 4G低功耗LTE无线通信模块
  18. 鹰潭:移动物联网产业领跑全国
  19. Python中itertools.product()函数调用
  20. 分分钟掌握人脸识别:face_recognition模块

热门文章

  1. Binary Agents
  2. Ajax提交数据判断员工编号是否存在,及自动填充与员工编号所对应的员工姓名。...
  3. maven local responsitory 手工新增jar
  4. 命令行添加删除tomcat服务
  5. LeetCode(344)——反转字符串(JavaScript)
  6. 塑料壳上下扣合的卡扣设计_塑胶产品结构设计--卡扣.pdf
  7. 月薪五万挖过来的高管第二天就离职了,为何公司总留不住优秀人才?
  8. 初二是学生阶段的分水岭吗?家长该做哪些准备?
  9. 鱼腥草可以随便吃吗?
  10. 股市最典型的穷人思维是什么?