write () для вывода stdout и printf не чередуются? - PullRequest
7 голосов
/ 07 августа 2009
#include <stdio.h>
#define MAXLEN 256

int main() {
  int n;
  char buf[MAXLEN];
  while((n = read(0,buf,sizeof(buf))) != 0){
    printf("n: %d:",n);
    write(1,buf,n);
  }
  return 1;
}

Вывод программы (где первый read и первый write набраны пользователем и отражены терминалом):

read
read
write
write
n: 5:n: 6:

Вывод printf происходит после нажатия Ctrl + D при стандартном вводе, а не вместе с последующими чтениями. Почему это происходит?

Ответы [ 5 ]

20 голосов
/ 07 августа 2009

Printf буферизован.

Вы можете заставить printf очистить свой буфер с помощью вызова fflush:

#include <stdio.h>
#define MAXLEN 256

int main() {
  int n;
  char buf[MAXLEN];
  while((n = read(0,buf,sizeof(buf))) != 0){
    printf("n: %d:",n);
    fflush(stdout); /* force it to go out */
    write(1,buf,n);
  }
  return 1;
}

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

Тем не менее, printf() буферизует вас, если вы также fprintf(stderr,) - stderr сознательно не буферизированы. Как следствие, вы можете получить ваши сообщения с отсутствующим printf(); если вы пишете в другой дескриптор FILE, который также связан с терминалом и может быть небуферизован, сначала убедитесь, что вы явно fflush(stdout).

2 голосов
/ 07 августа 2009

Справочная страница по fgets сообщает мне:

Не рекомендуется смешивать вызовы для ввода функций из stdio библиотека с низкоуровневыми вызовами read (2) для ассоциации дескриптора файла с входным потоком; результаты будут неопределенными и очень вероятно не то, что вы хотите.

Так что лучшим решением было бы не использовать write и printf для одного и того же дескриптора.

1 голос
/ 08 октября 2012

Вы можете использовать функцию std fflush () для очистки буфера std out или можете использовать дополнительный \ n в конце строки управления внутри printf. Как то так

printf("\n :%d:\n",n);

Всегда лучше использовать функции write () и read () в C вместо printf () и scanf (). У printf и scanf есть некоторые проблемы, например, printf сохраняет строковый параметр в буфере stdout. Поэтому требуется ручная очистка, которая выполняется с помощью функции fflush или с помощью \ n. В небольшой программе печати hello world вы не найдете такой проблемы, как буфер stdout сбрасывается в конце выполнения программы. Лучше использовать write (), которая работает нормально. У scanf также есть проблема с пространством для чтения и множеством других проблем, связанных с буфером stdin.

Например, в коде ниже:

main()  {   char a; int i=0,c; for(;i<2;i++) { scanf("%d",&c); scanf("%c",&a);} }

Приведенная выше программа столкнулась с проблемой чтения \ n в stdin при нажатии enter. Мы могли бы решить эту проблему, но не очищать буфер stdin или использовать символ \ n. Всегда лучше использовать функции read () и write ().

Надеюсь, это поможет ....

1 голос
/ 07 августа 2009

Printf использует stdio и буферизуется. Выдвиньте его, отправив изменение в «n:% d: \ n»

0 голосов
/ 07 августа 2009

Используйте fwrite (потоковая версия) вместо записи.

Обратите внимание, что, хотя он связан с файлом № 1, это не одно и то же.

...