看板 C_and_CPP 關於我們 聯絡資訊
以下是標準的做法 stderr:預設沒有分配buffer stdout:預設有分配buffer cout:用stdout的buffer clog:用stderr的buffer cerr:用stderr的buffer,強制清空buffer 因為每個compiler的預設值可能不同,可能有人因此搞混,所以整理一下重點, 首先看cout.flags()、clog.flags()、cerr.flags()的值,大小為15個bit, 第二高的那個bit(即ios::unitbuf)若為1,代表會強制清空buffer,反之則否, 一般來說只有cerr會設這個bit,但不排除有全部都設的compiler存在, 接下來則要看該stream的buffer,像stderr預設為沒有,(clog跟cerr都是用stderr) 所以就比stdout早輸出,如果有compiler會偷偷跑fflush()的話,那就沒差了.... 因為有些不按照標準,沒分配buffer給stdout ======================================================================================= #include<iostream> char buf[10]; using namespace std; int main(){ setbuf(stderr,0);//為了避免compiler偷偷分配buffer給stderr cout<<"123"; clog<<"456"; cerr<<"789"; } 這裡只有cerr有設ios::unitbuf,輸出順序卻是456123789,而不是456789123, 原因是cerr.tie()=&cout,這代表當cerr要清空時,會先清空前面cout的buffer ======================================================================================= #include<iostream> char buf[10]; using namespace std; int main(){ setbuf(stderr,0); cout<<"123"; cerr<<"456"; clog<<"789"; } 順序換一下,就變成123456789 ======================================================================================= #include<iostream> char buf[10]; using namespace std; int main(){ setbuf(stderr,buf); cout<<"123"; clog<<"456"; cerr<<"789"; } 那麼把0改成buf會怎樣? 輸出會變成123456789,因為此時clog的buffer大小已經不為0了 ======================================================================================= #include<iostream> #include<iostream> char buf[10]; char buf[10]; using namespace std; using namespace std; int main(){ int main(){ cerr.tie(0); cerr.tie(0); setbuf(stderr,buf); setbuf(stderr,buf); cout<<"123"; cout<<"123"; clog<<"456"; cerr<<"456"; cerr<<"789"; clog<<"789"; } } 接下來看clog跟cerr對調會如何,首先將cerr跟cout的關聯去掉, 左邊的輸出是456789123,右邊的輸出是456123789, 因為左邊的cerr強制清空stderr的buffer,導致clog比cout更早輸出, 而右邊的clog就只能乖乖等結束的時候執行fflush() ======================================================================================= #include<iostream> char buf[10]; using namespace std; int main(){ setbuf(stderr,buf); cout.setf(ios::unitbuf); cerr.unsetf(ios::unitbuf); clog.unsetf(ios::unitbuf); cerr<<"123"; clog<<"456"; cout<<"789"; } 讓cout反其道而行的方法,輸出為789123456,setbuf那行若改回0,則為123456789 ======================================================================================= #include<iostream> #include<iostream> char buf[10]; char buf[10]; using namespace std; using namespace std; int main(){ int main(){ setbuf(stderr,buf); setbuf(stderr,0); fprintf(stdout,"123"); fprintf(stdout,"123"); fprintf(stderr,"456"); fprintf(stderr,"456"); } } 最後附上stderr跟stdout的範例 ,左邊是123456,右邊是456123 ======================================================================================= 另外用setbuf()時,buffer千萬不能是local, 因為最後執行fflush()時,main()已結束了 參考的spec: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3035.pdf -- C++ hello world標準寫法 http://nopaste.csie.org/fee97 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 140.134.226.149
diabloevagto:寫的不錯喔!不過建議分配三種輸出的時候,用比較好 06/06 14:52
diabloevagto:分辨的,譬如用AAAaaa111這樣會比較好分辨。 06/06 14:53
※ 編輯: loveflames 來自: 140.134.226.149 (06/06 15:23)
nowar100:推您的熱心 06/06 16:16
突然想到有些東西忘了講,再補充一下 ======================================================================================= #include<iostream> char buf[10]; using namespace std; int main(){ setbuf(stderr,buf); cerr<<"123"; clog<<"456"; cout<<"789"; } 輸出是123789456,因為執行exit()後,先flush stdout,再flush stderr (標準好像沒有規定順序,應該跟下面的例子類似) ======================================================================================= #include<iostream> char buf[10]; using namespace std; int main(){ setbuf(stderr,buf); clog<<"123"; cout<<"456\n"; } 因為stdout是line buffered,所以先輸出456,兩個順序對調的話,則是123456 (stdout是line buffered似乎不是標準,而是implementation-defined,標準只說 要有buffer,不過好像多數compiler預設都是line buffered,還沒看過不是的) ======================================================================================= #include<iostream> char buf[10]; using namespace std; int main(){ setbuf(stderr,buf); cout<<"123"; clog<<"456\n"; } endl跟\n的不同是,前者有flush的作用,後者只是單純換行, 這個程式的輸出為123456,如果把\n改成endl,則先輸出456 ======================================================================================= ※ 編輯: loveflames 來自: 140.134.226.149 (06/06 19:52)