Почему этот код с использованием 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

12
Вы отключили синхронизацию и спросили, почему они не синхронизированы%)
добавлено автор RiaD, источник
Вы отключили синхронизацию и спросили, почему они не синхронизированы%)
добавлено автор RiaD, источник
Вы отключили синхронизацию и спросили, почему они не синхронизированы%)
добавлено автор RiaD, источник
Отдельные буферы?
добавлено автор Kerrek SB, источник
Отдельные буферы?
добавлено автор Kerrek SB, источник
@KerrekSB это точно, и я не хочу украсть у вас ответ. printf и cout используют отдельные буферы, которые очищаются в разное время. В случае вышеуказанного кода cout, скорее всего, был сброшен в линию, а printf был сброшен в конце вызова. Замените пространство в printf чем-нибудь другим (_), и вы увидите его.
добавлено автор IdeaHat, источник
@KerrekSB это точно, и я не хочу украсть у вас ответ. printf и cout используют отдельные буферы, которые очищаются в разное время. В случае вышеуказанного кода cout, скорее всего, был сброшен в линию, а printf был сброшен в конце вызова. Замените пространство в printf чем-нибудь другим (_), и вы увидите его.
добавлено автор IdeaHat, источник
@KerrekSB это точно, и я не хочу украсть у вас ответ. printf и cout используют отдельные буферы, которые очищаются в разное время. В случае вышеуказанного кода cout, скорее всего, был сброшен в линию, а printf был сброшен в конце вызова. Замените пространство в printf чем-нибудь другим (_), и вы увидите его.
добавлено автор IdeaHat, источник
Добавить fflush (stdout) ?
добавлено автор Columbo, источник
Добавить fflush (stdout) ?
добавлено автор Columbo, источник
Добавить fflush (stdout) ?
добавлено автор Columbo, источник
Этот вопрос не имеет большого смысла; с явно десинхронизованными стандартными потоками с stdio, вы спрашиваете, почему они ведут себя так, как будто они были синхронизированы?
добавлено автор T.C., источник
Этот вопрос не имеет большого смысла; с явно десинхронизованными стандартными потоками с stdio, вы спрашиваете, почему они ведут себя так, как будто они были синхронизированы?
добавлено автор T.C., источник
Этот вопрос не имеет большого смысла; с явно десинхронизованными стандартными потоками с stdio, вы спрашиваете, почему они ведут себя так, как будто они были синхронизированы?
добавлено автор T.C., источник
@ T.C. Вопрос не имеет большого смысла, если вы точно знаете, что происходит, я имею в виду, что на самом деле делает вызов ios_base :: sync_with_stdio (false) . Возможно, эта строка здесь только для улучшения производительности операций ввода-вывода с использованием cin/cout
добавлено автор Reynaldo Aguilar, источник
@ T.C. Вопрос не имеет большого смысла, если вы точно знаете, что происходит, я имею в виду, что на самом деле делает вызов ios_base :: sync_with_stdio (false) . Возможно, эта строка здесь только для улучшения производительности операций ввода-вывода с использованием cin/cout
добавлено автор Reynaldo Aguilar, источник
@ T.C. Вопрос не имеет большого смысла, если вы точно знаете, что происходит, я имею в виду, что на самом деле делает вызов ios_base :: sync_with_stdio (false) . Возможно, эта строка здесь только для улучшения производительности операций ввода-вывода с использованием cin/cout
добавлено автор Reynaldo Aguilar, источник

15 ответы

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

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

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

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

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

10
добавлено
Довольно уверен, что cout также flushes для строк новой строки, хотя большинство istreams этого не делают.
добавлено автор Mooing Duck, источник
@MooingDuck: из того, что я прочитал, cout сбрасывает символы новой строки при выводе на интерактивное устройство, такое как терминал, но не сбрасывается при записи в файл.
добавлено автор therainmaker, источник

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

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

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

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

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

10
добавлено
Довольно уверен, что cout также flushes для строк новой строки, хотя большинство istreams этого не делают.
добавлено автор Mooing Duck, источник
@MooingDuck: из того, что я прочитал, cout сбрасывает символы новой строки при выводе на интерактивное устройство, такое как терминал, но не сбрасывается при записи в файл.
добавлено автор therainmaker, источник

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

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

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

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

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

10
добавлено
Довольно уверен, что cout также flushes для строк новой строки, хотя большинство istreams этого не делают.
добавлено автор Mooing Duck, источник
@MooingDuck: из того, что я прочитал, cout сбрасывает символы новой строки при выводе на интерактивное устройство, такое как терминал, но не сбрасывается при записи в файл.
добавлено автор therainmaker, источник

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

8
добавлено

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

8
добавлено

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

8
добавлено

Попробуй это

    cout << i << " " <
5
добавлено

Попробуй это

    cout << i << " " <
5
добавлено

Попробуй это

    cout << i << " " <
5
добавлено

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

std::ios_base::sync_with_stdio(true);

не

std::ios_base::sync_with_stdio(false);

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

3
добавлено

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

std::ios_base::sync_with_stdio(true);

не

std::ios_base::sync_with_stdio(false);

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

3
добавлено

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

std::ios_base::sync_with_stdio(true);

не

std::ios_base::sync_with_stdio(false);

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

3
добавлено

Вероятно, вы пропустите 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;
}

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

1
добавлено
@ReynaldoAguilar Я исправил это.
добавлено автор πάντα ῥεῖ, источник
Он производит тот же вывод
добавлено автор Reynaldo Aguilar, источник

Вероятно, вы пропустите 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;
}

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

1
добавлено
@ReynaldoAguilar Я исправил это.
добавлено автор πάντα ῥεῖ, источник
Он производит тот же вывод
добавлено автор Reynaldo Aguilar, источник

Вероятно, вы пропустите 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;
}

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

1
добавлено
@ReynaldoAguilar Я исправил это.
добавлено автор πάντα ῥεῖ, источник
Он производит тот же вывод
добавлено автор Reynaldo Aguilar, источник
pro.cxx
pro.cxx
3 049 участник(ов)

C/C++ chat 0. Простые вопросы, лабы и о IDE — в чат новичков @supapro 1. Не хамим, не переходим на личности, не вбрасываем утверждения без доказательств 2. No Ads, offtop, flood Объявления о вакансиях и евенты - в лс @AlexFails https://t.me/ProCxx/259155

supapro.cxx
supapro.cxx
1 925 участник(ов)

Чат для тех, кто немного знает C++, простые вопросы по реализации, синтаксису и ide – сюда, а для другого есть: /Главный чат по серьезным вопросам — @ProCxx /Чат по обсуждению всего — @fludpac

C++ Russia
C++ Russia
384 участник(ов)

Сообщество разработчиков C++ в Telegram.

cxx.Дискуссионная
cxx.Дискуссионная
298 участник(ов)

это не двач, общайтесь вежливо; разговор на почти любые темы; Не согласны с баном? В лс @AlexFails, @ivario

C++ для маленьких и тупых
C++ для маленьких и тупых
105 участник(ов)

Лоу левел (по среднему IQ участников) чатик ExtremeCode @extremecode Флудилка @extremecode_rest