如果stdout被重定向,printf必須呼叫flout(stdout)才能重繪緩沖區
例如
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
int fd;
close(STDOUT_FILENO);
fd = open("hello", O_CREAT|O_RDWR, 0644);
if(fd < 0){
perror("open");
exit(0);
}
printf("Nice to meet you!\n");
fflush(stdout);//如果不呼叫fflush,nice to meet you 就不會被寫入到檔案
close(fd);
return 0;
}
但是我又發現了如下問題,十分奇怪,請大家解惑
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(void)
{
int fd;
printf("-------------1----------------\n");//加了這個printf即使不flush(stdout);也會正常寫入檔案,這是為什么
close(STDOUT_FILENO);
fd = open("hello", O_CREAT|O_RDWR, 0644);
if(fd < 0){
perror("open");
exit(0);
}
printf("Nice to meet you!\n");
//fflush(stdout);
close(fd);
return 0;
}
uj5u.com熱心網友回復:
#include <stdio.h>
int main() {
FILE* file = freopen("out.txt", "w", stdout);
if (file) {
printf("Nice to meet you!\n");
}
}
.... 我貌似記得fflush(stdout);不是標準?
uj5u.com熱心網友回復:
幫頂
uj5u.com熱心網友回復:
http://en.cppreference.com/w/c/io/fflushuj5u.com熱心網友回復:
printf里面的%和變數的一一對應關系scanf里面的%和變數以及變數前加不加&的一一對應關系
是C代碼中非常容易出錯的地方,而且通常編譯還不出錯。
所以在編譯源代碼之前值得專門仔細檢查一遍甚至多遍。
在每個最后不帶\n的printf后面加fflush(stdout);
在每個不想受接識訓沖區舊內容影響的scanf前面加rewind(stdin);
另外請檢查scanf的回傳值。
//請今后要用
int c;
scanf("%c",&c);
//時,都改為
char s[2];
int c;
scanf("%1s",s);
c=s[0];
uj5u.com熱心網友回復:
版主,不好意思,我明白加fflush重繪緩沖區,但還是不明白為什么關閉stdout前加了printf就不用fflush了uj5u.com熱心網友回復:
版主,不好意思,我明白加fflush重繪緩沖區,但還是不明白為什么關閉stdout前加了printf就不用fflush了
uj5u.com熱心網友回復:
感謝回復,不過不太明白和我的問題的聯系在哪里,不好意思請指教uj5u.com熱心網友回復:
prinf函式時可能會重繪緩沖區
uj5u.com熱心網友回復:
http://en.cppreference.com/w/c/io/fflush
版主,不好意思,我明白加fflush重繪緩沖區,但還是不明白為什么關閉stdout前加了printf就不用fflush了
prinf函式時可能會重繪緩沖區
uj5u.com熱心網友回復:
為什么兩個printf時第二個就重繪緩沖區,而一個printf的時候就沒有重繪
http://en.cppreference.com/w/c/io/fflush
版主,不好意思,我明白加fflush重繪緩沖區,但還是不明白為什么關閉stdout前加了printf就不用fflush了
prinf函式時可能會重繪緩沖區
第一個的時候你不是還沒打開檔案
uj5u.com熱心網友回復:
感覺樓主這里混淆了兩套概念。linux C語言檔案讀寫有兩套API,一套是open,close,read這一類API,這些函式是系統呼叫,open回傳的fd是一個整型數。還有一套API是C標準庫中的fopen,fclose,fread等等,這是一類帶緩沖的檔案操作API,其中fopen回傳的是一個FILE型別的指標。樓主的代碼里貌似混用了這兩套API,如果統一使用C標準庫中以f開頭的那些檔案讀寫函式,是否還會出現這些問題?uj5u.com熱心網友回復:
stdout默認是行緩沖的,也就是遇到\n重繪緩沖。你把它關了,重新打開的話,肯定緩沖模式就重置了。http://man7.org/linux/man-pages/man3/setbuf.3.html
setvbuf可以用設定為行緩沖或者無緩沖。
的確close、open屬于無緩沖的API,所以close檔案是不會同步緩沖的。
你應該用freopen("redir.txt", "w", stdout)這樣用支持緩沖的方式重新打開檔案stdout,
這樣當你fclose時就會正確同步檔案了。
uj5u.com熱心網友回復:
//請今后要用int c;
scanf("%c",&c);
//時,都改為
char s[2];
int c;
scanf("%1s",s);
c=s[0];
uj5u.com熱心網友回復:
行緩沖方式被改變,緩沖區滿,重繪。uj5u.com熱心網友回復:
遇到跟樓主一樣的問題,請問樓主解決了嗎?請教一下,為什么在close(1)之前加了printf后之后的printf可以正常輸出呢?謝謝uj5u.com熱心網友回復:
遇到跟樓主一樣的問題,請問樓主解決了嗎?請教一下,為什么在close(1)之前加了printf后之后的printf可以正常輸出呢?謝謝
uj5u.com熱心網友回復:
我也好奇。。按理說應該被改成全緩沖了啊?uj5u.com熱心網友回復:
版主,不好意思,我明白加fflush重繪緩沖區,但還是不明白為什么關閉stdout前加了printf就不用fflush了
幫頂
首先:printf的緩沖有多重情況,標準輸出是行緩沖,重定向到檔案是全緩沖,而系統呼叫是不帶緩沖的。所以在重定向后它是全緩沖,所以printf("Nice to meet you!\n");中"\n"不能刷緩沖,所以此時如果不呼叫fflush,nice to meet you 就不會被寫入到檔案。
其次如果在重定向之前呼叫了 printf("-------------1----------------\n");//加了這個printf即使不flush(stdout);也會正常寫入檔案,這是為什么
這句話,那么 printf 在重定向之后還是行緩沖,并沒有變為全緩沖。在行緩沖中"\n"具有刷緩沖的功能。所以printf("Nice to meet you!\n");
可以寫入檔案中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/22510.html
標籤:C語言
