15

I have the following code:

int main ()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);    

    for (int i = 0; i < 3; i++) {
        cout << i << " ";
        printf("%d ", i);
    }

    cout << endl;
    return 0;
}

The expected output of this code is:

0 0 1 1 2 2

but, instead, it prints:

0 1 2
0 1 2

This issue happens in GNU G++ 4.9.2 compiler

dgvid
  • 26,293
  • 5
  • 40
  • 57
Reynaldo Aguilar
  • 1,906
  • 1
  • 15
  • 29
  • 2
    @KerrekSB that is exactly it and I don't want to steal the answer from you. printf and cout use separate buffers that are flushed at different times. In the case of the above code, cout was most likely flushed in line, and printf was flushed at the end of the call. Replace the space in the printf with something else (_) and you'll see it. – IdeaHat Apr 15 '15 at 17:56
  • Add `fflush(stdout)`? – Columbo Apr 15 '15 at 18:02
  • 4
    This question doesn't make much sense; having explicitly de-synced standard streams with stdio, you ask why they behave as though they were de-synced? – T.C. Apr 15 '15 at 20:06
  • 1
    @T.C. The question doesn't make much sense if you know exactly what is happening, I mean, what the call to `ios_base::sync_with_stdio(false)` actually do. Maybe this line is here just for improve performance of I/O operations using cin/cout – Reynaldo Aguilar Apr 15 '15 at 20:13
  • You turned off sync yourself and ask why they are not synced %) – RiaD Apr 15 '15 at 20:42

5 Answers5

12

One possible explanation for this is that cout and printf use separate buffers. cout outputs on the terminal screen either when it is flushed using the endl command, or if the buffer is full (generally 512 bytes).

I am not sure about printf (so feel free to correct me if I'm wrong), but it also follows a similar behaviour. So what happens is that at the end of the program, both the buffers are flushed, and so the output you see is achieved.

I ran the code on my machine (GCC 4.8.1) along with the modification as below

cout << i << " . ";
printf("%d ", i);

The output I observed was 0 1 2 0 . 1 . 2 . which seems to indicate that printf flushes first in my case. I have no idea if it is by design (mentioned somewhere in the standard), or if it depends on the context.

therainmaker
  • 4,253
  • 1
  • 22
  • 41
  • Pretty sure `cout` also flushes for newlines, though most istreams don't. – Mooing Duck Apr 15 '15 at 18:03
  • 1
    @MooingDuck : From what I have read, `cout` flushes for newlines when outputting to an interactive device, such as the terminal, but doesn't flush when writing to a file. – therainmaker Apr 15 '15 at 18:09
9

By default the C stdio functions printf, etc. and the C++ io streams are synchronized meaning they can be used interchangeably. At the beginning of your code you have removed the synchronization with ios_base::sync_with_stdio(false) not sure if your actual intent was to write this ios_base::sync_with_stdio(true) which synchronizes the two io libraries.

ALXGTV
  • 362
  • 3
  • 12
5

Try this

    cout << i << " " <<std::flush;
    printf("%d ", i);
    fflush(stdout);
itachi
  • 192
  • 2
  • 10
3

If you want the output std::cout and printf to be sync'ed, you'll need to use:

std::ios_base::sync_with_stdio(true);

not

std::ios_base::sync_with_stdio(false);

See it working at http://ideone.com/7sgH2I.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

You probably miss to flush() std::cout. printf() has a different behavior regarding this. Also the IO buffers should be synchronized. If you change your code to

int main () {
    ios_base::sync_with_stdio(true); // Synchronizing the IO buffers
                                     // must be enabled
    cin.tie(NULL);    

    for (int i = 0; i < 3; i++) {
        cout << i << " ";
        cout.flush(); // <<<<<<<<<<
        printf("%d ", i);
    }

    cout << endl;
    return 0;
}

it should behave as you expected. See the working demo here please.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190