如何解释ios_base::sync_with_stdio(false);cin.tie (NULL);

How do I interpret this behavior of ios_base::sync_with_stdio(false); cin.tie(NULL);?

本文关键字:cin stdio false NULL tie with base 何解释 解释 ios sync      更新时间:2023-10-16

其实我是通过下面的答案才知道快速输入/输出的,https://stackoverflow.com/a/31165481/6108030

问题1:

它说如果我使用ios_base::sync_with_stdio(false);,它将禁用C和c++风格输入/输出之间的同步。因此,根据我的解释,这意味着通过使用这个语句,我将无法在我的c++代码中使用scanf()(即C风格的I/O)(如果我错了,请纠正我)。

但我的代码仍然工作,即使使用ios_base::sync_with_stdio(false);

代码如下:

int main()
{
  ios_base::sync_with_stdio(false);
  long test; cin>>test;
  while(test--)
  {
       ull f=0,t=0,a,b,c,d,k;
       scanf("%llu %llu %llu %llu %llu",&a,&b,&c,&d,&k); //scanf() used
       while(f<k){                  //
         t++;                       //Irrelevant from a question perspective
         f=a*(t*t*t)+b*(t*t)+c*t+d; //
       }                            //
       if(f==k)
        cout<<(t)<<"n";
       else
        cout<<(t-1)<<"n";
}}
/* Expected behaviour
  2             input(no of test)
  2 2 2 2 10    input(a b c d k)
  1             output
  2 3 5 7 1000  input
  7             output
Behavior of this code
  2
  2 2 2 2 10    input
  2 3 5 7 1000  input(prompted)
  1             output
  7             output
*/

这背后的正确原因是什么?

问题2:

答案还指出,使用cin.tie(NULL)cincout分开。但是在上面的代码中,当我只使用cin.tie(NULL)而不是ios_base::sync_with_stdio(false);时,输出与上面在"预期行为"中提到的相同。节,而不是"此代码的行为"部分。

我还想知道ios_base::sync_with_stdio(false);cin.tie(NULL)是否相互关联,是否应该一起使用?

我正在寻找一个全面的解释这种行为。如果你能拿我的输入样本来解释的话会更有帮助。

你没有真正理解同步是什么意思,以及什么是标准输入和标准输出。

标准输入和标准输出是您过程的全局资源。每个过程有一个标准输入和一个标准输出。cin表示从标准输入中读取的单一方式。但scanf是另一种读取方式。

标准输入是全局的。所以如果一种读取数据的方法读取了一些东西,然后另一种方法出现并试图读取这些东西,那么第二个方法试图读取的东西可能已经不在那里了。下面是一个可能发生的例子。

语句cin >> test;将从标准输入中读取一些内容。多少钱的东西?好吧,它将读取至少足够以获得单个long类型。但cin完全有能力阅读更多内容。通常,cin将根据内部缓冲区大小读取数据。

目前,您的初始输入只是2 <return>。然而,这并不是必须的。可能是2 2 2 2 2 10 <return>cin >> test;仍然只读取单个整数。其余的将是未读输入,将由下一个cin read命令处理。

然而,未读输入实际上仍然在全局标准输入中吗?可能不是;cin可能会读取所有数据并将其塞进内部缓冲区。一旦发生这种情况,标准输入将不包含任何内容。哦,是的,使用cin将处理2 2 2 2 10输入的其余部分。

但是使用scanf不会。为什么?因为它不知道cin的内部缓冲区。它只从标准输入读取scanf也是如此。它可以有自己的内部缓冲区的未读输入,cin不能读取。

好吧,除非你同步两个系统。这正是sync_with_stdio的作用:当它被设置为true时(默认为),对标准流的操作将在两个系统之间工作。cin可以读取一些字符,scanf可以读取其他一些字符,两者都不会丢失任何内容。

如果您不同步它们,那么您不应该尝试在同一个应用程序中使用两个系统。这样做会有输入丢失的风险,或者输出没有按正确的顺序出现。


cin.tie的行为正是你链接到的答案所说的:它确保写入标准输出的内容将在任何尝试从标准输入读取之前显示给用户。

但是,这只适用于cincoutscanf不一定参与这种绑定行为(无论同步是否激活)。因此,cout语句是否会在scanf语句开始从标准输入读取之前向标准输出显示任何内容是未定义的。

所以cin.tie不适用于你

问题1

不,这并不意味着你不能同时使用两个I/o,但是同时使用两个I/o会导致非常难以预测的结果(两个I/o的交错是非常难以预测的)。

因此,不应该在同一代码中同时使用

。在c++中总是使用c++ I/o。只有在使用使用C I/o的外部库时才使用该控件。

问题2

No tiesync_with_stdio无关。tie背后的基本思想是确保在获得输入之前总是打印提示符。cout绑定到cin意味着cout将在任何cin使用之前被刷新(如果需要的话)。