-1

Actually I came to know about fast input/output through following answer, https://stackoverflow.com/a/31165481/6108030.

Question 1:

It says that if I use ios_base::sync_with_stdio(false);, it will disable the synchronization between C and C++ style input/output. So according to my interpretation it means that by using this statement I won't be able to use scanf() (i.e C style I/O) in my C++ code (correct me if I got it wrong).

But my code is still working even after using ios_base::sync_with_stdio(false);.

Here's the code.

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
*/

What could be the right reason behind this?

Question 2:

The answer also stated that using cin.tie(NULL) unties cin from cout. But in the above code when I just used cin.tie(NULL) and not ios_base::sync_with_stdio(false); the output was same as mentioned above in the "Expected behavior" section instead of that in "Behavior of this code" section.

Also I want to know whether ios_base::sync_with_stdio(false); and cin.tie(NULL) are interrelated and should be used together or not?

I am looking for a comprehensive explanation for this behavior. It will be more helpful if you'll take my input samples for the explanation.

Community
  • 1
  • 1
  • 1
    No, it only means that combining `printf` with `cout` and `scanf` with `cin` will lead to undefined behavior, as they will use separate buffering. – Šimon Tóth Jun 28 '16 at 12:02
  • This should be useful: http://en.cppreference.com/w/cpp/io/ios_base/sync_with_stdio – Galik Jun 28 '16 at 12:10
  • Also this: http://en.cppreference.com/w/cpp/io/cin – Galik Jun 28 '16 at 12:12
  • @Let_Me_Be this is not undefined behavior, standard just says that I/Os are just independent: *called with a false argument, it allows the standard streams to operate independently of the standard C streams*. It is very difficult to predict what happens but it is predictable. – Jean-Baptiste Yunès Jun 28 '16 at 12:38

2 Answers2

1

Question 1

No, this doesn't means that you can't use both, but that using both I/Os at the same time leads to very difficult result prediction (interleaving of both I/Os are very hard to predict).

For that reason, you should not use both in the same code. In C++ always use C++ I/Os. Use that control only when using an external library that uses C I/Os.

Question 2

No tie is not related to sync_with_stdio. The basic idea behind tie is to ensure that a prompt is always printed before getting input. couttied to cin means that cout will be flushed (if needed) before any cin use.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
1

The thing you're not really understanding is what it means to synchronize with things, as well as what standard input and standard output really are.

Standard Input and Standard Output are global resources for your process. Each process has one Standard Input and one Standard Output. cin represents a single way of reading from Standard Input. But scanf is another way of reading from it.

Standard Input is global. So if one method of reading data reads something, then another one comes along and tries to read stuff, well the stuff the second one tried to read may not be there anymore. Here's an example of how that might happen.

The statement cin >> test; will read something from standard input. How much something? Well, it will read at least enough to get a single long type. But cin is perfectly capable of reading much more than that. Typically, cin will read data based on an internal buffer size.

Currently, your initial input is just 2 <return>. However, it doesn't have to be. It could have been 2 2 2 2 2 10 <return>. cin >> test; will still only read a single integer. The rest will be unread input, which will be processed by the next cin read command.

However, will that unread input actually still be in the global Standard Input? Probably not; cin will likely read all of that data and shove it into an internal buffer. Once that happens, Standard Input contains nothing. Oh yes, using cin will process the rest of the 2 2 2 2 10 input.

But using scanf will not. Why? Because it doesn't know about cin's internal buffer. It only reads from Standard Input. And the same goes for scanf. It can have its own internal buffer of unread input, and cin can't read that.

Well, not unless you synchronize the two systems. That is exactly what sync_with_stdio is for: when it is set to true (as it defaults to), operations on the standard streams will work between the two systems. cin can read some characters, and scanf can read some others, and neither will miss anything.

If however you do not synchronize them, then you shouldn't try to use both systems in the same application. To do so runs the risk of input going missing, or output not appearing in the right order.


The behavior of cin.tie is exactly what the answer you linked to says: it ensures that stuff written to Standard Output will be displayed to the user before any attempts to read from Standard Input take place.

However, this only applies to cin and cout. scanf does not necessarily participate in such tying behavior (whether synchronization is active or not). As such, it is undefined if the cout statements will display anything to Standard Output before the scanf statements start reading from Standard Input.

So cin.tie does not apply to you.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • The OP first used `cin>>t` for which 2 gets into `t` and you said that the subsequent inputs are inserted into `cin's internal buffer`. Since, user has done `ios_base::sync_with_stdio(false);` and we know that now scanf and cin have independent buffers, then why is are rest of the inputs inserted into cin's buffer rather than scanf reading them the next time. I expected cin and scanf to work independtly and not interfere with each other's job. – asn May 11 '20 at 11:10
  • Now, later during `scanf("%llu %llu %llu %llu %llu",&a,&b,&c,&d,&k)`, since scanf is used, how does cin inserts these values into a,b,c,d when it doesn't know anything aboutt what scanf is doing(bcz. they are now independent). – asn May 11 '20 at 11:14