Странное поведение std::cout в Linux

Я пытаюсь распечатать результаты за 2 вложенных цикла for, используя std::cout. Однако результаты выводятся на консоль не сразу, а с задержкой (после завершения цикла for или программы).

Не считаю такое поведение нормальным, под виндой печать работает нормально. Программа не использует потоки.

Где может быть проблема? (Убунту 10.10 + NetBeans 6.9).


person johny    schedule 25.03.2011    source источник
comment
О какой задержке вы говорите?   -  person karlphillip    schedule 25.03.2011
comment
Вы когда-нибудь печатали endl? Это должно очистить буфер   -  person Cameron    schedule 25.03.2011
comment
Кода нет, обычная печать в двух вложенных циклах for. В коде анализировать нечего :-))   -  person johny    schedule 25.03.2011
comment
Как отметил Кэмерон, похоже, что вы не очищаете буфер, используя std::endl (запись новой строки и сброс буфера) или std::flush (просто сброс буфера).   -  person Peter Huene    schedule 25.03.2011
comment
@Cameron: проблема возникает при печати точки, представляющей% обработанных данных.   -  person johny    schedule 25.03.2011
comment
@johny: Нам не пришлось бы задавать все эти вопросы, если бы вы опубликовали код. Обычная печать едва ли достаточно конкретна, чтобы мы могли помочь, разве что угадывая   -  person Cameron    schedule 25.03.2011


Ответы (2)


std::cout — это поток, и он буферизован. Смыть его можно несколькими способами:

std::cout.flush();

std::cout << std::flush;

std::cout << std::endl;  // same as:  std::cout << "\n" << std::flush`


Джонни:

Я очищаю буфер перед циклом, используя std::endl. Проблема возникает при печати точки, представляющей % обработанных данных внутри цикла.

Если вы очищаете буфер перед циклом, это не влияет на вывод в цикле. Вы должны смыть в или после цикла, чтобы увидеть вывод.

person MacGucky    schedule 25.03.2011
comment
Я очищаю буфер перед циклом, используя std::endl. Проблема возникает при печати точки, представляющей % обработанных данных внутри цикла. - person johny; 25.03.2011
comment
@johny: Вам нужно выполнить сброс внутри цикла, иначе cout может отложить печать на столько, сколько захочет. Если вам не нужны новые строки, используйте std::flush вместо std::endl. - person aschepler; 25.03.2011
comment
@aschepler - я хотел бы добавить (хотя это не важно для вашего случая), что ::std::cout не может откладывать «сколь угодно долго». Во-первых, если вы читаете данные с помощью ::std::cin, произойдет сброс. Во-вторых, он должен сбрасываться до завершения вашей программы, если она завершается обычным возвратом из main (даже если этот возврат не равен нулю). Кроме того, очистка буфера стоит дорого, не делайте этого без необходимости (в том числе с использованием ::std::endl). - person Omnifarious; 26.03.2011

Если вы не сбрасываете свой вывод, не гарантируется, что ваш вывод будет виден за пределами вашей программы. Тот факт, что он не печатается в вашем терминале, является просто следствием поведения по умолчанию в Linux для буферизации строк, когда вывод является tty. Если вы запустите свою программу в Linux, а ее вывод будет направлен на другую вещь, например

 ./your_program | cat

Тогда буфер по умолчанию будет НАМНОГО больше, скорее всего он будет не менее 4096 байт. Таким образом, ничего не будет отображаться, пока большой буфер не заполнится. но на самом деле поведение зависит от ОС, если вы не сбросите std::cout самостоятельно.

Чтобы очистить std::cout, используйте:

std::cout << std::flush;

также, используя

std::cout << std::endl;

это ярлык для

std::cout << '\n' << std::flush;
person BatchyX    schedule 25.03.2011