代码之家  ›  专栏  ›  技术社区  ›  spicypumpkin

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

  •  4
  • spicypumpkin  · 技术社区  · 8 年前

    这个标题有误导性,因为我更感兴趣的是找到另一种解决方案。我的直觉是,检查缓冲区是否为空不是最理想的解决方案(至少在我的情况下)。

    我是C++新手,一直在遵循Bjarne Stroustrup使用C++的编程原则和实践。我现在在第7章,我们正在“细化”第6章中的计算器(我将在问题的末尾提供源代码的链接)

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

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

    但我想去掉最后两个答案的提示字符(“>”),只在要求用户输入时再次显示。我的第一反应是找到一种方法来检查缓冲区是否为空,如果为空,则输入字符,如果不是,则继续输入答案。但在谷歌搜索了一番之后,我意识到这项任务并不像我最初想象的那么简单……而且,也许从一开始就不是一个好主意。

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

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

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

    ^您需要这个头文件。我想这是作者自己写的。

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

    1 回复  |  直到 8 年前
        1
  •  1
  •   Sam Varshavchik    8 年前

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

    C++库

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

    int n;
    
    std::cin >> n;
    

    让我们说,当这件事结束后, n 包含数字 42 .嗯,实际上发生的是 std::cin ,很可能不仅仅读取了两个字符“4”和“2”,但除此之外,在 std::cin 流动其余字符存储在 std::streambuf ,下一个输入操作将在实际读取基础文件之前读取它们。

    同样可能的是 >> 实际上没有从文件中读取任何内容,而是从 std::streambuf ,在上一次输入操作后留在那里。

    可以检查底层 std::streambuf ,并确定是否有未读的内容。但这对你没什么帮助。

    如果您要执行上述操作 >> 操作员,您查看了底层 std::streambuf ,并发现它包含一个字符“4”,这也不会告诉你太多。你需要知道下一个角色是什么 std::cin .它可以是空格或换行符,在这种情况下,您将从 >> 运算符为4。或者,下一个字符可以是“2”,在这种情况下 >> 将吞下至少“42”,并可能吞下更多数字。

    您当然可以自己实现所有这些逻辑,看看底层 std::streambuf ,并确定它是否满足即将进行的输入操作。祝贺您:您刚刚重新发明了 >> 操作人员您也可以自己解析输入,一次解析一个字符。

    基础文件

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

    这现在成为操作系统特定的主题。标准C++库不再涵盖这一点。

    结论

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