有没有办法偷看stdin缓冲区?
我们知道stdin
默认是一个缓冲输入; 证据就是使用了在stdin
上“保留数据”的任何机制,例如scanf()
:
int main() { char c[10] = {'\0'}; scanf("%9s", c); printf("%s, and left is: %d\n", c, getchar()); return 0; }
./a.out
你好
你好,左边是10
10
当然是新行……
我一直很好奇,有没有办法“偷看” stdin
缓冲区而不删除那里可能存在的东西?
编辑
一个更好的例子可能是:
scanf("%9[^.]", c);
输入“at.ct”,现在我在stdin
留下了“数据”( ct\n
),而不仅仅是换行符。
或者,您可以使用getchar()
获取输入流中的下一个字符,然后使用ungetc()
将其推回,这会导致状态,就好像该字符未从流中删除一样。
ungetc
函数将c
指定的字符(转换为unsigned char
)推回到stream指向的输入流。 按推送的相反顺序,后续读取该流将返回推回的字符。
标准只保证了一个回击角色,但通常情况下,你可以更多地推回。
正如其他答案所述。 那里的评论,实际上,如果你使用setvbuf
提供自己的缓冲区,你几乎可以肯定地查看缓冲区,尽管这不是没有问题:
如果
buf
不是空指针,则可以使用它指向的数组而不是setvbuf
函数分配的缓冲区
这留下了可能根本不使用所提供的缓冲区的可能性。
任何时候数组的内容都是不确定的。
这意味着您无法保证缓冲区的内容反映实际输入(如果它具有自动存储持续时间,如果我们挑剔则使用缓冲区未定义的行为)。
然而,在实践中,主要问题是找出缓冲区中尚未消耗的部分开始的位置和结束位置。
您可以在stdin上使用setvbuf
设置自己的缓冲区,并随时查看。
如果你想在不改变它的情况下查看stdin
缓冲区,你可以告诉它使用另一个带setbuf
缓冲区,使用你可以访问的数组:
char buffer[BUFSIZ]; if (setbuf(stdin, buffer) != 0) // error getchar(); printf("%15s\n", buffer);
这让你看到的东西比ungetc
更多,但我认为你不能以便携的方式走得更远。
实际上这是合法的,但对于标准来说是不正确的,引用它来讨论setvbuf
( setbuf
具有相同的行为):
任何时候数组的内容都是不确定的。
因此,如果您正在寻找完全可移植性和标准兼容性,那么这不是您所需要的,但我无法想象为什么缓冲区不应包含预期的内容。 但是,它似乎可以在我的电脑上运行。
请注意,您必须为setbuf
提供至少BUFSIZ
字符的数组,并且您不能在它之前对流执行任何I / O操作。 如果您需要更多灵活性,请查看setvbuf
。