stderr和stdout详细解说

<cstdio>ios

objectc++

stderr缓存

FILE * stderr;app

Standard error stream函数

The standard error stream is the defaultdestination for error messages and other diagnostic warnings. Like stdout, itis usually also directed by default to the text console (generally, on thescreen).测试

 

stderr can be used as an argument for anyfunction that takes an argument of type FILE* expecting an output stream, likefputs or fprintf.this

 

Although in many cases both stdout andstderr are associated with the same output device (like the console),applications may differentiate between what is sent to stdout and what tostderr for the case that one of them is redirected. For example, it is frequentto redirect the regular output of a console program (stdout) to a file whileexpecting the error messages to keep appearing in the console.spa

 

It is also possible to redirect stderr tosome other destination from within a program using the freopen function..net

 

stderr is is never fully buffered onstartup. It is library-dependent whether the stream is line buffered or notbuffered by default (see setvbuf).orm

 

stderr和stdout详细解说

今天又查了一下fprintf,其中对第一个参数stderr特别感兴趣。

int fprintf(FILE *stream,char*format,[argument]);

在此以前先区分一下:printf,sprintf,fprintf。

1,printf就是标准输出,在屏幕上打印出一段字符串来。

2,sprintf就是把格式化的数据写入到某个字符串中。返回值字符串的长度。

3,fprintf是用于文件操做。

     原型:int fprintf(FILE *stream,char *format,[argument]);      

     功能:fprintf()函数根据指定的format(格式)发送信息(参数)到由stream(流)指定的文件.所以fprintf()可使得信息输出到指定的文件。

例子:

#include <iostream>

#include <stdio.h>

using namespace std;

 

int main()

{

    char name[] = "lucy";

    FILE* out;

    out = fopen("output.txt""w");

    if(NULL != out)

    {

        int rel =fprintf(out,"Hello %s\n", name);

        cout<< "写入了" << rel << "个字符" << endl;

    }

 

    system("pause");

    return 0;

}

返回值:若成功则返回输出字符数,若输出出错则返回负值。

好了,以上到此为止。

而后深挖stdout,stderr。

stdout, stdin, stderr的中文名字分别是标准输出标准输入标准错误

当一个用户进程被建立的时候,系统会自动为该进程建立三个数据流,也就是题目中所提到的这三个。那么什么是数据流呢(stream)?咱们知道,一个程序要运行,须要有输入、输出,若是出错,还要能表现出自身的错误。这是就要从某个地方读入数据、将数据输出到某个地方,这就够成了数据流。

所以,一个进程初期所拥有的这么三个数据流,就分别是标准输出、标准输入和标准错误,分别用stdout, stdin, stderr来表示。。这3个文件分别为标准输入(stdin)、标准输出(stdout)、标准错误(stderr)。它们在<stdio.h>中声明,大多数环境中,stdin指向键盘,stdout、stderr指向显示器。之因此使用stderr,若因某种缘由形成其中一个文件没法访问,相应的诊断信息要在该连接的输出的末尾才能打印出来。当输出到屏幕时,这种处理方法尚可接受,但若是输出到一个文件或经过管道输出到另外一个程序时,就没法接受了。如有stderr存在,即便对标准输出进行了重定向,写到stderr中的输出一般也会显示在屏幕上。好比咱们在c++中使用fprintf:

fprintf(stdout,"hello world!\n");

屏幕上将打印出"helloworld!"来。

一样,咱们使用:fread(ptr,1,10,stdin);

上面的代码会接收用户输入在终端里的字符,并存在ptr中。

那么标准输入输出和错误是否是只能反应在终端里呢?答案是否是的!咱们能够将标准输入和输出重定位到文件中:

1,咱们知道,标准输出和标准错误默认都是将信息输出到终端上,那么他们有什么区别呢?让咱们来看个题目:

问题:下面程序的输出是什么?(intel笔试2011)

int main(){

fprintf(stdout,"Hello ");

fprintf(stderr,"World!");

return0;

}

 

解答:这段代码的输出是什么呢?,而后发现输出是:

World!Hello

 

这是为何呢?在默认状况下,stdout是行缓冲的,他的输出会放在一个buffer里面,只有到换行的时候,才会输出到屏幕。而stderr是无缓冲的,会直接输出,举例来讲就是fprintf(stdout, "xxxx") 和 fprintf(stdout,"xxxx\n"),前者会缓存,直到遇到新行才会一块儿输出。而fprintf(stderr, "xxxxx"),无论有么有\n,都输出。

 

2,fprintf(stderr,"Can't open it!\n");

fprintf(stdout, "Can't open it!\n");

printf("Can't open it!\n");

这3句效果不是同样啊,有什么区别吗?

有区别。

stdout -- 标准输出设备

stderr -- 标准错误输出设备

二者默认向屏幕输出。

但若是用转向标准输出到磁盘文件,则可看出二者区别。stdout输出到磁盘文件,stderr在屏幕。

C++stderr/stdout 重定向到文件

一般,stderrstdout被用来输出内容显示到屏幕,可是,有时候咱们须要把这些信息写到指定的文件,方便随时查阅。最简单的实现方式就是,把 stderr/stdout 的输出重定向到文件。

stderr/stdout重定向到文件

这里以stderr代码说明。

#include<stdio.h>

#include<stdlib.h>

intmain(  )

{

 FILE *stream = freopen("freopen.out", "w", stderr );

 if( stream == NULL )

    fprintf( stdout, "error onfreopen\n" );

 else

{

    fprintf( stdout, "successfullyreassigned\n" ); fflush( stdout );

    fprintf(stream, "This will Go to the file 'freopen.out'\n" );

    fprintf( stderr, "Also you can do it likethis!\n" );

    fclose(stream );

 }

 // windwos下读取文件 freopen.out

 system( "type freopen.out" );

 getchar();

 return 0;

}

执行结果以下,


stderr与stdout的区别

stdout(标准输出),输出方式是行缓冲。输出的字符会先存放在缓冲区,等按下回车键时才进行实际的I/O操做。

stderr(标准出错),是不带缓冲的,这使得出错信息能够直接尽快地显示出来。

关于缓冲的说明:

关于缓冲的说明:

类型

说明

输出状况

满缓冲

I/O操做只有在缓冲区被填满以后才会进行

1.缓冲区满

2.刷出数据 (fflush

3.关闭文件 (fclose)

行缓冲

一般只有遇到换行符时,才会执行实际的I/O操做;但缓冲区满也会强制执行

1.遇到换行符

2.缓冲区满

3.刷出数据 (fflush

4.关闭文件 (fclose)

无缓冲

不缓存,直接进行I/O操做

直接输出

然而就缓冲来讲,stdout与stderr没有绝对的区别,由于缓冲类型能够设定。这里要借助setvbuf() 或setbuf() 函数。

#include<stdio.h> 

#include<stdlib.h>  

 

intmain() 

   

 char buf[512] = {0};

 setbuf(stderr, buf);

 fprintf(stderr, "It is error 1\n");

 printf("echo 1\n");

 fprintf(stderr, "It is error 2\n");

 printf("echo 2\n");

 fprintf(stderr, "It is error 3\n");

 

 fflush(stderr);

 

 getchar();

 return 0;

}

运行结果以下:


这样,咱们就能够定义缓冲区大小。缓冲区默认大小由stdio.h 头文件中的宏 BUFSIZ定义,是512字节。另外,查阅一些资料说最小不能低于256字节,但测试例子没有这个问题(暂时没有深究)。

setvbuf()与setbuf()

setvbuf()函数原型以下:

intsetvbuf ( FILE * stream, char * buffer, int mode, size_t size );

setbuf()能够看成是调用setvbuf(stream,buf, buf ? _IOFBF : _IONBF, BUFSIZE);

其中, mode是声明缓冲的类型,以下几个:

_IOFBF

满缓冲

_IOLBF

行缓冲

_IONBF

无缓冲

size是缓冲区大小,单位字节。

/*setvbuf example */

#include<stdio.h>

intmain ()

{

  FILE *pFile=fopen("myfile.txt","w");

  setvbuf ( pFile , NULL , _IOFBF , 1024 );

  // File operations here

  fclose (pFile);

  return 0;

}