почему эта программа c не печатает первый оператор printf? - PullRequest
6 голосов
/ 09 ноября 2011
#include<stdio.h>
#include <unistd.h>
int main(){
      while(1)
      {

              fprintf(stdout,"hello-out");
              fprintf(stderr,"hello-err");
              sleep(1);
      }
      return 0;
}

При компиляции этой программы в gcc и при ее выполнении выводится только hello-err, а не hello-out. Почему это так? Может кто-нибудь объяснить причину этого?

Ответы [ 3 ]

17 голосов
/ 09 ноября 2011

Если вы добавите '\n' к вашему сообщению, оно будет (или должно), т.е. "hello-out\n".

Причина в том, что stdout является буферизованным , чтобы быть более эффективным, тогда как stderr не буферизует его вывод и больше подходит для сообщений об ошибках и вещей, которые необходимо распечатать немедленно.

stdout будет обычно будет покраснел когда:

  • Будет напечатана новая строка (\n)
  • Вы читаете с stdin
  • fflush() вызывается на нем

РЕДАКТИРОВАТЬ: Еще одна вещь, которую я хотел добавить, прежде чем мой компьютер вышел из строя ... дважды ... было то, что вы также можете использовать setbuf(stdout, NULL);, чтобы отключить буферизацию stdout. Я делал это раньше, когда мне приходилось использовать write() (Unix), и я не хотел, чтобы мой вывод был буферизован.

3 голосов
/ 09 ноября 2011

Это не всегда распечатывает вывод в stdout, потому что по конструкции stdout является выходом BUFFERED, а stderr небуферизован. В общем случае для буферизованного потока вывода поток не выгружается до тех пор, пока система не станет «свободной» для этого. Таким образом, данные могут продолжать буферизоваться в течение длительного времени, прежде чем они будут сброшены. Если вы хотите принудительно очистить буфер, вы можете сделать это вручную, используя fflush

#include<stdio.h>
#include <unistd.h>
int main(){
      while(1)
      {

              fprintf(stdout,"hello-out");
              fflush(stdout); /* force flush */
              fprintf(stderr,"hello-err");
              sleep(1);
      }
      return 0;
}

Обновление: stdout буферизуется при подключении к терминалу и просто буферизуется иначе (например, перенаправление или канал)

1 голос
/ 09 ноября 2011

Вы забыли символы новой строки (отмечено \n) в ваших строках.Или вам нужно позвонить fflush(NULL); или хотя бы fflush(stdout);, прежде чем sleep(1);

И fprintf(stdout, ...) будет таким же, как printf(...)

Вам необходимо вывести новые строки или позвонить1011 *, потому что (по крайней мере, в Linux) буфер stdout FILE буферизован строкой.Это означает, что библиотека C буферизует данные и действительно выводит их (используя системный вызов write Linux ), когда буфер заполнен достаточно, или когда вы очищаете его либос новой строкой или по телефону fflush.Буферизация необходима, потому что системные вызовы являются дорогостоящими (вызов write для каждого выводимого байта действительно слишком медленный).Читайте также справочную страницу setbuf

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...