C ++如何检查std :: cin缓冲区是否为空

时间:2017-01-22 01:13:07

标签: c++ cin

标题具有误导性,因为我对寻找替代解决方案更感兴趣。我的直觉是检查缓冲区是否为空并不是最理想的解决方案(至少在我的情况下)。

我是C ++的新手,并且一直在使用C ++关注Bjarne Stroustrup的编程原理和实践。我现在正在第7章,在那里我们正在精炼"第6章中的计算器。(我将在源代码的末尾放置源代码的链接。)

基本上,计算器可以从用户那里获取多个输入,由分号分隔。

> 5+2; 10*2; 5-1;
          = 7
>         = 20
>         = 4
> 

但是我想删除最后两个答案的提示字符('>'),并且仅在要求用户输入时再次显示它。我的第一直觉是找到一种方法来检查缓冲区是否为空,如果是,则对该字符进行cout,如果没有,则继续提示回答。但经过一番谷歌搜索后,我意识到这项任务并不像我最初想的那么容易......而且也许这不是一个好主意。

我想基本上我的问题是如何摆脱'>'当有多个输入时,最后两个答案的字符。但是,如果检查cin缓冲区 是可能的并且毕竟是一个坏主意,我很想知道如何去做。

源代码:https://gist.github.com/Spicy-Pumpkin/4187856492ccca1a24eaa741d7417675

标题文件:http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h

^你需要这个头文件。我认为它是由作者本人写的。

编辑:我确实在网上寻找一些解决方案,但说实话,他们都没有任何意义。自从我学习C ++以来,它已经过了4天,而且我的编程背景非常薄,所以有时甚至用谷歌搜索都有点困难......

1 个答案:

答案 0 :(得分:1)

正如您所发现的,这是一项看似复杂的任务。这是因为这里有许多问题,包括C ++库和实际的底层文件。

C ++库

std::cin和C ++输入流使用中间缓冲区std::streambuf。来自底层文件或交互式终端的输入不是逐字符读取的,而是在可能的情况下以中等大小的块读取。让我们说:

int n;

std::cin >> n;

假设完成此操作后,n包含数字42。嗯,实际发生的事情是std::cin,很可能不会只读取两个字符,'4'和'2',但除此之外的任何其他字符都可以在std::cin流中获得。其余字符存储在std::streambuf中,下一个输入操作将在实际读取基础文件之前读取它们。

同样可能的是,上面的>>实际上没有从文件中读取任何内容,而是从std::streambuf中取出了'4'和'2'字符,这些字符留在那里在上一次输入操作之后。

可以检查基础std::streambuf,并确定那里是否有未读的内容。但这对你没有帮助。

如果您要执行上面的>>运算符,则会查看基础std::streambuf,并发现它包含单个字符'4',这也不会告诉您太多。您需要知道std::cin中的下一个字符是什么。它可以是空格或换行符,在这种情况下,您从>>运算符获得的所有内容都是4.或者,下一个字符可能是'2',在这种情况下>>将吞下至少'42',可能还有更多的数字。

您当然可以自己实现所有这些逻辑,查看基础std::streambuf,并确定它是否能满足您即将进行的输入操作。恭喜:您刚刚彻底改造了>>运营商。你也可以自己解析输入,一次解析一个角色。

基础文件

您确定std::cin没有足够的输入来满足您的下一个输入操作。现在,您需要知道std::cin上是否有输入。

现在这成为特定于操作系统的主题。标准C ++库不再包含它。

结论

这是可行的,但在所有实际情况中,这里最好的解决方案是使用特定于操作系统的方法,而不是C ++输入流,并自己读取和缓冲输入。例如,在Linux上,经典的方法是将fd 0设置为非阻塞模式,以便read()不会阻塞,并确定是否有可用输入,只需尝试read()它。如果您确实阅读了某些内容,请将其放入缓冲区,稍后您可以查看。一旦你消耗了所有先前读取的缓冲输入,你真的需要等待更多的输入被读取,poll()文件描述符,直到它在那里。