为什么我们需要绑定std :: cin和std :: cout?

std*_*std 18 c++ c++-standard-library

默认情况下,标准输入设备与标准输出设备绑定在一起: 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;
}
Run Code Online (Sandbox Code Playgroud)

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

use*_*631 19

您的示例中没有任何错误(除了您应该cin.tie(0)在行后添加分号),也没有iostream对象的工作方式.

tie()只需保证coutcin执行输入之前刷新.这对于用户在被要求回答之前查看问题很有用.

但是,如果这不同于tie()cincout,没有保证的缓冲区cout被刷新.但是不能保证缓冲区也不会被刷新.实际上,如果计算机有足够的资源,它将立即刷新cout缓冲区,因此在请求输入之前会发生这种情况.在您的示例中就是这种情况.cin

所以,一切都运作良好.除此之外,cin.tie(0)不保证会发生冲洗.但是,在99%的情况下,仍然会发生冲洗(但不再保证).

从理论上讲,如果打成平手,cincout可以共享相同的缓冲区.但是,我认为没有实现这样做.一个原因是两者可能是un-tie()d.

  • 挑剔第二点:示例代码中 `cout` 被刷新的原因与“资源”无关——这是因为默认情况下启用了与 stdio 的同步,因此刷新是由 stdio 的策略进行的。在(交互式)windows 环境中,默认情况下,stdio 输出流是完全无缓冲的,因此输出会立即发生。(在这种情况下,linux 更喜欢行缓冲,因此示例代码不会刷新,除非缓冲区太小以至于提示填满它) (3认同)
  • 小问题:如果(底层的“streambuf”)“cin”必须向环境请求更多输入,则该平局仅保证“cout”将刷新。如果“cin”的输入缓冲区包含足够的数据来满足读取请求,您将不会获得刷新。 (2认同)

Kon*_*rov 6

我认为,以前的答案是错误的(我想知道为什么它被如此高票并标记为正确,显然不是)。

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

像这样:

std::cin.tie (nullptr);
std::cout.sync_with_stdio(false);
std::cout << "Please enter c: ";
std::cin >> c;
Run Code Online (Sandbox Code Playgroud)

然后你保证有未绑定的流。与 stdio 同步是一种特殊能力,以便在对 C 样式和 C++ 样式的输入和输出进行排序之后进行适当的处​​理,我强烈建议您在没有真正必要的情况下将其删除。