2010-05-02 91 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