2010-05-02 55 views
0

所以如果我這樣做:,流仍包含舊內容?

dup2(0, backup); // backup stdin 
dup2(somefile, 0); // somefile has four lines of content 
fgets(...stdin); // consume one line 
fgets(....stdin); // consume two lines 
dup2(backup, 0); // switch stdin back to keyboard 

我在這一點上找到..標準輸入仍然包含兩行我還沒有消耗。這是爲什麼?因爲無論您重定向多少次,都只有一個緩衝區?我如何擺脫剩下的兩條線,但是當我想回到它時,仍然記得我在somefile流中的位置?

回答

5

您沒有刷新stdin緩衝區。即使底層文件描述符已被恢復,它也會緩衝某些文件的所有行。

+0

dang ...打我一秒鐘。 :) +1 – falstro 2010-05-02 12:28:46

+0

是的,好吧,我現在setbuf爲NULL ...無論如何,告訴我,stdin是否有一個緩衝區,並且每當你重定向到另一個流時,它都會將該流中的內容添加到它的緩衝區中,即使你重定向到別的地方,它仍然存在嗎? – BobTurbo 2010-05-02 12:50:20

+0

是默認情況下stdio的東西有文件數據的緩衝區。 dup2()等使用的文件描述符在用戶級別完全沒有緩衝。不幸的是(對於你;-),文件描述符調用並不知道上層的stdio調用,並且不會做任何事情來確保當你更改文件描述符時,stdio緩衝區保持同步。 – 2010-05-02 13:59:05

0
dup2(0, backup); // backup stdin 
dup2(somefile, 0); // somefile has four lines of content 
fgets(...stdin); // consume one line 
fgets(....stdin); // consume two lines 
dup2(backup, 0); // switch stdin back to keyboard 
+0

第一行應該是'backup = dup(0);'。否則,如果另一個文件被打開併發生與備份相同的fd,則會遇到各種令人討厭的錯誤(更不用說與線程競爭了!)。 – 2010-07-26 12:27:51