有什么办法在标准输入缓冲区偷看?(Is there any way to peek at the s

2019-07-17 12:10发布

我们知道, 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”的输入,现在我有“数据”( ct\n )留在stdin ,而不仅仅是一个换行符。

Answer 1:

可移植的,你可以在输入流中的下一个字符用getchar()然后用其推回ungetc()这会导致状态如果字符不是从物流中除去。

ungetc功能通过按压指定的字符c (转换为unsigned char )返回到输入流由流指向。 通过随后在其推动的相反顺序流中读取被推回的字符将被退回。

只有推回一个字符是由标准的保证,但通常情况下,你可以推回了。

正如在其他的答案中提到的RESP。 还有的意见,在实践中,你几乎可以肯定是在偷看缓冲区如果您提供您自己的缓冲区setvbuf ,尽管这也不是没有问题的:

如果buf是不是一个空指针,阵列它指向可以替代地使用由分配的一个缓冲器的setvbuf功能

离开所提供的缓冲可能无法使用在所有的可能性。

所述阵列的在任何时间的内容是不确定的。

这意味着你不能保证缓冲区的内容反映了实际输入(它使得使用缓冲区不确定的行为,如果它具有自动存储时间,如果我们挑剔)。

然而,在实践中,主要问题将被找出,其中在缓冲器中的缓冲的输入的还未消耗部分开始并在此结束。



Answer 2:

你可以设置自己的缓冲与setvbuf对标准输入,并且只要你想偷看那里。



Answer 3:

如果你想看看stdin缓冲区,而不改变它,你可以告诉它使用与另一个缓冲区setbuf ,使用数组,您可以访问:

char buffer[BUFSIZ];

if (setbuf(stdin, buffer) != 0)
  // error

getchar();

printf("%15s\n", buffer);

这让你看到的东西比更ungetc ,但我不认为你可以走得更远在便携式的方式。

其实这是合法的,但不正确的标准,从它引述有关setvbufsetbuf具有相同的行为):

所述阵列的在任何时间的内容是不确定的。

因此,这是不是你需要的,如果你正在寻找完整的便携性和标准的遵守,但我不能想象为什么缓冲区不应包含的期望是什么。 然而,它似乎在我的电脑上工作。

要注意的是,你必须提供至少数组BUFSIZ字符setbuf和之前你不能做流中的所有I / O操作。 如果您需要更多的灵活性,看看setvbuf



文章来源: Is there any way to peek at the stdin buffer?