Почему printf() не печатает ничего перед сном()?
Я просто изучаю C с книгой Kernighan и Ritchie; Я вхожу в основы четвертой главы (функции). На днях мне стало интересно узнать о функции sleep()
, поэтому попытался использовать ее так:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
printf(" I like cows.");
sleep(5);
return 0;
}
Проблема заключается в выходе программы, она выглядит как сначала sleep()
, а затем printf()
, другими словами, она ждет пять секунд и затем печатает строку. Поэтому я подумал, может быть, программа добирается до sleep()
настолько быстро, что не позволяет printf()
выполнять свою работу так, как я хочу, то есть печатать строку, а затем спать.
Как я могу показать строку, а затем перевести программу в режим сна?
Компилятор GCC 3.3.5 (прополис) в OpenBSD 4.3.
PS Я не знаю, как правильно поставить строки препроцессора.
Ответы
Ответ 1
printf()
записывается в stdout
(выходной поток по умолчанию), который обычно буферизируется по строке. Буфер не сбрасывается ко времени sleep
, так что ничего не отображается, когда программа выходит из всех потоков, автоматически очищается, и поэтому она печатается прямо перед выходом. Печать новой строки обычно приводит к покраске потока, альтернативно вы можете использовать функцию fflush
:
int main(void)
{
printf(" I like cows.\n");
sleep(5);
return 0;
}
или
int main(void)
{
printf(" I like cows.");
fflush(stdout);
sleep(5);
return 0;
}
Если вы печатаете в потоке, который не является буфером строки, как это может быть в случае, если stdout
перенаправляется или вы пишете файл, просто печать новой строки, вероятно, не будет работать. В таких случаях вы должны использовать fflush
, если вы хотите, чтобы данные были записаны немедленно.
Ответ 2
Ваша проблема в том, что printf (и все, что использует библиотеку stdio для записи в stdout (стандартный вывод)) буферизуется - буферизируется в строке, если она идет на консоль, и размер буферизуется, если он идет в файл. Если вы выполните fflush(stdout);
после printf
, он сделает то, что вы хотите. Вы можете попробовать просто добавить новую строку ('\n') в свою строку, и это будет сделано правильно, если вы не перенаправляете стандартный вывод в файл.
Я не уверен на 100%, но я думаю, что stderr
не буферизирован, что может вызвать путаницу, потому что вы можете увидеть вывод, который вы сделали для stderr
, перед выводом, ранее сделанным в stdout
.
Ответ 3
Буферизация означает, что весь вывод хранится в месте (называемом буфером) и выводится после того, как в нем присутствует определенное количество данных. Это делается по соображениям эффективности.
Некоторые (большинство?) реализаций очищают буфер после новой строки при записи на консоль, поэтому вы также можете попробовать
printf(" I like cows.\n");
вместо вызова функции fflush()
Ответ 4
Я реализовал время встречи следующим образом;
for (int i = 1; i <= 60; i++) {
printf("%02d", i);
fflush(stdout);
sleep(1);
printf("\b\b");
}