Почему этот код с использованием printf и cout не имеет ожидаемого результата?

У меня есть следующий код:

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;
}

Ожидаемый вывод этого кода:

0 0 1 1 2 2

но вместо этого он печатает:

0 1 2
0 1 2

Эта проблема возникает в компиляторе GNU g++ 4.9.2

Ответ 1

Одним из возможных объяснений этого является то, что cout и printf используют отдельные буферы. cout выводится на экран терминала либо при его сбросе с помощью команды endl, либо если буфер заполнен (как правило, 512 байтов).

Я не уверен в printf (так что не стесняйтесь исправить меня, если я ошибаюсь), но это также следует за аналогичным поведением. Итак, что происходит, так это то, что в конце программы оба буфера очищаются, и поэтому результат, который вы видите, достигается.

Я запустил код на своей машине (GCC 4.8.1) вместе с модификацией ниже

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

Результат, который я наблюдал, был 0 1 2 0 . 1 . 2 ., который, по-видимому, указывает, что printf сначала сбрасывается в моем случае. Я понятия не имею, если это по дизайну (упоминается где-то в стандарте), или если это зависит от контекста.

Ответ 2

По умолчанию функции stdio C printf и т.д. и потоки С++ io синхронизированы, что означает, что они могут использоваться взаимозаменяемо. В начале кода вы удалили синхронизацию с ios_base::sync_with_stdio(false), не уверен, что ваше фактическое намерение заключалось в написании этого ios_base::sync_with_stdio(true), который синхронизирует две библиотеки io.

Ответ 3

Попробуйте это

    cout << i << " " <<std::flush;
    printf("%d ", i);
    fflush(stdout);

Ответ 4

Если вы хотите, чтобы выходные данные std::cout и printf были синхронизированы, вам необходимо использовать:

std::ios_base::sync_with_stdio(true);

не

std::ios_base::sync_with_stdio(false);

Посмотрите, как работает http://ideone.com/7sgH2I.

Ответ 5

Вероятно, вы пропустите flush() std::cout. printf() имеет другое поведение относительно этого. Также буферы IO должны быть синхронизированы. Если вы измените свой код на

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;
}

он должен вести себя так, как вы ожидали. См. Рабочую демонстрацию здесь.