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)缓冲区即将溢出

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

 #include <stdio.h>

 int main(int argc, const char *argv[])
{
fprintf(stdout, "hello world");
while(); return ;
}

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

将代码修改如下:

 #include <stdio.h>

 int main(int argc, const char *argv[])
{
fprintf(stdout, "hello\nworld");
while(); return ;
}

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

将代码修改如下:

 #include <stdio.h>

 int main(int argc, const char *argv[])
{
fprintf(stdout, "hello world");
fclose(stdout);
while(); return ;
}

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

将代码修改如下:

 #include <stdio.h>

 int main(int argc, const char *argv[])
{
fprintf(stdout, "hello world");
fflush(stdout);
while(); return ;
}

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

将代码修改如下:

 #include <stdio.h>

 int main(int argc, const char *argv[])
{
int i; for (i = ; i < ; i++) {
fprintf(stdout, "a");
} while(); return ;
}

终端将显示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:缓冲区大小

将代码修改如下:

 #include <stdio.h>

 int main(int argc, const char *argv[])
{
setvbuf(stdout, NULL, _IONBF, );
fprintf(stdout, "a"); while(); return ;
}

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

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

 #include <stdio.h>

 int main(int argc, const char *argv[])
{
int i; setvbuf(stdout, NULL, _IOLBF, );
for (i = ; i < ; i++) {
fprintf(stdout, "a");
} while(); return ;
}

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

修改代码如下:

 #include <stdio.h>

 int main(int argc, const char *argv[])
{
int i;
char buf[]; setvbuf(stdout, buf, _IOLBF, );
for (i = ; i < ; i++) {
fprintf(stdout, "a");
} while(); return ;
}

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

这让我产生一种感觉:

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

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

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

五、stdout,stdoin和stderr的更多相关文章

  1. 关于print()、sys.stdout、sys.stderr的一些理解

    print() 方法的语法: print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False) 其中file = sys.stdout的 ...

  2. python sys.stdin、sys.stdout和sys.stderr

    学习并转载自  https://www.cnblogs.com/guyuyuan/p/6885448.html 标准输入:一般是键盘.stdin对象为解释器提供输入字符流,一般使用raw_input( ...

  3. python重定向sys.stdin、sys.stdout和sys.stderr

    转自:https://www.cnblogs.com/guyuyuan/p/6885448.html 标准输入.标准输出和错误输出. 标准输入:一般是键盘.stdin对象为解释器提供输入字符流,一般使 ...

  4. stdin、stdout、stderr

    1 ferror 2 stdin 3 stdout 4 stderr 1 ferror 功能:检测文件是否出现错误 返值:未出错0,出错非0 说明:每次调用文件输入输出函数,均产生一个新的ferror ...

  5. Linux Shell 文件描述符 及 stdin stdout stderr 重定向

    Abstract: 1) Linux Shell 命令的标准输入.标准输出.标准错误,及其重定位: 2)Linux Shell 操作自定义文件描述符: 文件描述符是与文件相关联的一些整数,他们保持与已 ...

  6. stderr和stdout详细解说

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

  7. stderr 和stdout

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

  8. 标准输出中stderr和stdout的区别

    一.首先介绍一下三者printf,sprintf,fprintf的功能 1,printf就是标准输出,在屏幕上打印出一段字符串来. 2,sprintf就是把格式化的数据写入到某个字符串中.返回值字符串 ...

  9. 【python】print · sys.stdout · sys.stderr

    参考文档 Python重定向标准输入.标准输出和标准错误 http://blog.csdn.net/lanbing510/article/details/8487997 python重定向sys.st ...

随机推荐

  1. SQLserver提示事务日志已满无法重建索引,前台提示日志已满处理方案

    1.数据库--属性--选项--恢复模式:简单. 2.数据库--任务--文件类型:日志                            在释放未使用的空间潜重新组织页:1M 3.数据库--属性-- ...

  2. .NET+MySql 踩坑1

    换成MySql数据库后,遇到的问题: 已解决,但不理解的问题: var test = db.test; 报如下图错误: 加上DefaultIfEmpty()则解决. var test = db.Tes ...

  3. [cf contest 893(edu round 33)] F - Subtree Minimum Query

    [cf contest 893(edu round 33)] F - Subtree Minimum Query time limit per test 6 seconds memory limit ...

  4. 维修数列 Splay(这可能是我写过最麻烦的题之一了。。。用平衡树维护dp。。。丧心病狂啊。。。。)

    题目来源BZOJ1500 这题的思路: 1.这题的话,稍微会splay的人,一般前面四个都不是问题..主要是最后的一个,要你在修改的同时要维护好最大字段和... 2.最大字段和其实就是区间合并.具体操 ...

  5. centos7上keepalived的安装和配置

    1.环境规划1)master:node1,centos7.5,eth0:192.168.1.11,eht1:10.10.1.11,keepalive2)backup:node1,centos7.5,e ...

  6. 常用adb 指令

    adb指令 monkey https://www.cnblogs.com/aland-1415/p/6949964.html

  7. C#设计模式(0)-设计模式系列文章导航

    设计模式系列文章导航  C#设计模式(1)——单例模式(SingletonPattern) C#设计模式(2)——简单工厂模式(SimpleFactory)    C#设计模式(3)——工厂方法模式( ...

  8. Flask框架基础--第一篇

    1.flask框架和其他几种框架的优缺点对比 Django : 优点 - 大而全所有组件都是有组织内部开发高度定制化 教科书级别的框架 缺点 - 大到浪费资源,请求的时候需要的资源较高 Flask : ...

  9. javaScript简单的留言板

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  10. thinkphp5和thinkphp3.2.3中URL重写出现No input file specified

    查询后解决办法是打开public目录下的.htaccess文件,把:RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] 改为:RewriteRule ^(.*)$ i ...