22

默认情况下,标准输入设备与标准输出设备以下列形式绑定在一起: std::cin.tie (&std::cout);保证在调用输入之前输出缓冲区已被刷新。所以我尝试使用 解开它们std::cin.tie(0),但结果似乎与已绑定的没有区别。

#include<iostream>
using namespace std;

int main(int argc, char *argv[])
{
    char c;

    cin.tie(0)

    cout << "Please enter c:";
    cin >> c;
    cout << c ;

    return 0;
}

我测试错了吗?为什么我们需要将它们捆绑在一起?它们共享相同的缓冲区吗?

4

3 回答 3

27

您的示例没有任何问题(除了您应该在该行之后添加一个分号cin.tie(0)),也没有 iostream 对象的工作方式。

tie()只是保证执行输入cout之前的刷新。cin这对于用户在被要求回答之前查看问题很有用。

但是,如果您取消from ,tie()则无法保证刷新的缓冲区。但是不能保证缓冲区也不会被刷新。事实上,如果计算机有足够的资源,它会立即刷新缓冲区,所以这发生在请求输入之前。在您的示例中就是这种情况。cincoutcoutcoutcin

所以,一切正常。除了 之后cin.tie(0),不能保证会发生刷新。但是,在 99% 的情况下,仍会发生冲洗(但不再保证)。

理论上,如果捆绑,cin可以cout共享同一个缓冲区。但是,我认为没有任何实现可以做到这一点。一个原因是这两者可能是 un-tie()d。

于 2012-12-27T10:01:31.143 回答
6

我认为,以前的答案是错误的(我想知道为什么它如此受欢迎并被标记为真实,显然不是)。

要打破之前发生的关系,您应该(仅在标准 io 的情况下)(1)删除与 stdio 的同步(2)解开流。

像这样:

std::cin.tie (nullptr);
std::cout.sync_with_stdio(false);
std::cout << "Please enter c: ";
std::cin >> c;

然后,您可以保证有未绑定的流。与 stdio 同步是一种特殊能力,以便在 C 样式和 C++ 样式输入和输出的排序之后发生正确的事件,我强烈建议您不要在没有真正必要的情况下删除它。

于 2017-02-24T19:01:43.003 回答
1

在 C 中,提示用户输入遵循您发出命令以打印提示消息,然后发出命令以输入值的模式。

为了使此过程正常工作,您需要确保实际显示提示消息。配置环境以便这是自动的:

  • 在 DOS(或 windows 命令行)环境中,STDOUT是无缓冲的,因此 print 命令会立即显示该消息。
  • 在 *NIX 环境中,STDOUT是行缓冲的。因此,如果您遵循 *NIX 样式,在提示消息中包含换行符,以便用户在下一行输入输入,那么您的提示将在输入之前自动显示。

tie 特性使这种自动刷新行为成为 iostream 库工作方式的一部分,而不是约定俗成的产物。(尽管请注意,自动刷新仅在程序要求系统获取更多输入时发生,因此存在cin >> c实际上不会刷新的极端情况)


然而!默认情况下,iostream 库与 stdio 库同步。实际上,这意味着 iostream 根本不做任何缓冲。它只是将数据转发到底层 C 库。

因此,这意味着您将看到如果您编写类似的 C 程序时通常会看到的内容。如果您在 Windows 命令行环境中,则不会缓冲输出,因此您会在输入输入之前看到提示。

std::cout.sync_with_stdio(false);要查看本机 C++ 行为,您需要通过在程序开始时运行来关闭同步,如另一个答案中所示。

如果你这样做,那么cout语句将不会刷新输出缓冲区(除非缓冲区非​​常小)。并且由于您已经移除了领带,因此该cin声明也不会刷新它。因此,您将获得必须在看到提示之前输入用户输入的结果。

于 2018-06-30T18:09:51.563 回答