stderr和stdout详细解说

stderr和stdout详细解说cstdio>objectstderrFILE*stderr;StandarderrorstreamThestandarderrorstreamisthedefaultdestinationforerrormessagesandotherdiagnosticwarnings.Likestdout,itisusuall

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

<cstdio>

object

stderr

FILE * stderr;

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.

 

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.

 

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

 

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

 

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;

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/213414.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Sobel算子的理解

    Sobel算子的理解sobel算子主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测。原理算子使用两个33的矩阵(图1)算子使用两个33的矩阵(图1)去和原始图片作卷积,分别得到横向G(x)和纵向G(y)的梯度值,如果梯度值大于某一个阈值,则认为该点为边缘点Gx方向的相关模板:Gy方向的相关模板:看了网上的很多资料,都把卷积和相关的概念给弄糊了,书上

  • 使用instsrv.exe和srvany.exe将应用程序安装成windows后台服务

    使用instsrv.exe和srvany.exe将应用程序安装成windows后台服务windows系统下的自带的工具包介绍

  • db4o java_java com.db4o 类

    db4o java_java com.db4o 类packageorg.rx.repository.db4o.impl;importcom.db4o.Db4o;importcom.db4o.ObjectContainer;importcom.db4o.ObjectSet;importcom.db4o.config.Configuration;importlombok.SneakyThrows;importorg.rx.api.dto.common…

  • Populating Next Right Pointers in Each Node II LeetCode[通俗易懂]

    Populating Next Right Pointers in Each Node II LeetCode

  • SpringBoot常见面试问题

    SpringBoot常见面试问题博客转载自:https://blog.csdn.net/ityouknow/article/details/96533522随着SpringBoot使用越来越广泛,SpringBoot已经成为Java程序员面试的知识点,很多同学对SpringBoot理解不是那么深刻,经常就会被几个连环跑给干趴下了!比如下面这一段的SpringBoot问答:问:你觉得S…

  • https证书怎么申请?「建议收藏」

    https证书怎么申请?「建议收藏」来看一下https证书申请都需要什么?怎么安装呢?https是什么?http和https是我们上网的时候经常见到的网络协议,当我们进入一个网站的时候,网站的域名有时候是http开头的,有时候又是https开头的,可能你们会好奇,这两者究竟有什么区别呢?https证书又是什么呢?安装https的证书究竟有没有什么作用呢?安装https证书的步骤如何,是简单还是复杂呢?关于http和…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号