Почему printf () ничего не печатает перед сном ()? - PullRequest
17 голосов
/ 03 декабря 2008

Я только изучаю C с книгой Кернигана и Ричи; Я в основах четвертой главы (функции вещи). На днях мне стало интересно узнать о функции 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 (propolice) в OpenBSD 4.3.

PS Я не знаю, как вы правильно разместили строки препроцессора.

Ответы [ 4 ]

33 голосов
/ 03 декабря 2008

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, если хотите, чтобы данные записывались немедленно.

3 голосов
/ 03 декабря 2008

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

Некоторые (большинство?) Реализации очищают буфер после новой строки при записи в консоль, поэтому вы также можете попробовать

printf(" I like cows.\n");

вместо вызова fflush ()

3 голосов
/ 03 декабря 2008

Ваша проблема в том, что printf (и все остальное, что использует библиотеку stdio для записи в stdout (стандартный вывод)) буферизуется - строка буферизируется, если идет на консоль, и размер буферизуется, если идет в файл. Если вы сделаете fflush(stdout); после printf, он будет делать то, что вы хотите. Вы можете попробовать добавить новую строку ('\ n') к вашей строке, и это будет правильно, если вы не перенаправляете стандартный вывод в файл.

Я не уверен на 100%, но я думаю, что stderr не буферизуется, что может привести к путанице, потому что вы можете увидеть вывод, который вы сделали на stderr перед выводом, который вы ранее сделали на stdout.

0 голосов
/ 20 декабря 2018

Я реализовал время встречи следующим образом;

for (int i = 1; i <= 60; i++) {
    printf("%02d", i);
    fflush(stdout);
    sleep(1);
    printf("\b\b");
}
...