stderr,stdin,stdout相關


轉載請保留原作者。

一.stdin和stdout

1.意義

stdin表示標准輸入,stdout表示標准的輸出。它們都是文件指針。默認情況下,所指向的文件是控制台。
可以使用freopen進行重定向,或者fopen新建文件指針,都是可以的。

2.緩沖

2.1.scanf的緩沖問題

#include<stdio.h>
using namespace std;
int main(){
    int a;
    while(scanf("%d",&a)!=1)printf("error!");
    return 0;
}

這段代碼的原意是,如果讀入不到a,那么就輸出error。
但是,stdin中的內容,scanf不是按照行讀入字符,而是根據連續的字符流讀入字符。因此,如果讀入一個非法字符,例如非數字的字符,那么會出問題。因為讀入后,scanf發現錯誤,然后輸入error,再次讀入下一個字符時,上次的那個字符還殘留在流中,因此導致無限輸出error。

對於這個做法,有人會使用fflush(stdin),這個問題我們下一章節繼續。

2.2.fflush

一般來說,stdout是有緩沖的。緩沖的意思就是先把字符存起來,到達某一時刻,把緩存的字符一次性寫入文件。我們知道,硬盤速度比內存慢很多,每寫一個就存入一次速度很慢,如果累計起來一次放入速度會提高。
stdout默認是到達換行符刷新。

fflush一般用於輸出的緩沖刷新。也就是說,輸出到一半,使用fflush可以提前刷新。
但是fflush只能用於輸出的刷新,輸入流不能這樣刷新。fflush(stdin)可能在部分編譯器可以刷新輸入流,達到上文的scanf刷新,但是標准沒有定義這個行為。也就是說,部分編譯器是不支持的。

3.freopen

freopen(const char *filename,const char *mode,FILE *stream);
把stream重定向到filename的文件名去。
例如,freopen(“a.txt”,”r”,stdin);表示把a.txt作為輸入重定向stdin。這樣,默認scanf就會從a.txt讀入而不是控制台。
第二個參數mode,表示模式,例如r表示文本讀入,w表示文本寫入,rb表示二進制讀入等。

如果在重定向到文件后,重定向回控制台進行輸入輸出,可以把filename設置為“CON”即可。

二.stderr

1.輸出方法

標准錯誤流。fprintf(stderr,...);
使用fprintf指定文件指針為stderr,進行輸出,默認輸出文件還是stdout的文件。也就是說,也可以往控制台輸出,輸出位置一樣的。

2.默認緩沖

讓我們寫個程序檢驗一下。

#include<stdio.h>
using namespace std;
int main(){
    fprintf(stdout,"stdout ");
    fprintf(stderr,"stderr ");
}

輸出:stderr stdout
看上去stderr先輸出?沒錯,就是這樣,沒有換行符的時候,stdout不會自動刷新,但是stderr每寫一個字符都要刷新。因此,stderr先輸出,程序結束的時候再刷新一次,輸出stdout。

如果先加上fflush,那么就是stdout先了。

#include<stdio.h>
using namespace std;
int main(){
    fprintf(stdout,"stdout ");fflush(stdout);
    fprintf(stderr,"stderr ");
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM