Подтвердить что ты не робот

Является ли строка stdout буферной, небуферизованной или неопределенной по умолчанию?

Раздел 7.9.13/7 of c99 гласит, что:

При запуске программы три текстовых потока предопределены и их явно не нужно открывать - стандартный ввод (для чтения обычного ввода), стандартный вывод (для записи обычного вывода) и стандартная ошибка (для записи диагностического вывода).

Как первоначально было открыто, стандартный поток ошибок не полностью буферизирован; стандартные входные и стандартные выходные потоки полностью буферизуются тогда и только тогда, когда можно определить поток, чтобы не ссылаться на интерактивное устройство.

Итак, это имеет смысл. Если вы нажимаете свой стандартный вывод на файл, вы хотите, чтобы он полностью буферизировался для эффективности.

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

Я прошу прокомментировать мой ответ здесь, что я должен вставить fflush(stdout); между двумя утверждениями:

printf ("Enter number> ");
// fflush (stdout); needed ?
if (fgets (buff, sizeof(buff), stdin) == NULL) { ... }

потому что я не завершал printf символом новой строки. Может кто-нибудь прояснить это?

4b9b3361

Ответ 1

В стандарте C99 не указывается, являются ли три стандартных потока небуферизованными или строковыми: Это зависит от реализации. Все реализации UNIX, которые я знаю, имеют буферизированную строку stdin. В Linux stdout в строке буферизируется и stderr небуферизован.

Насколько я знаю, POSIX не налагает дополнительных ограничений. POSIX fflush страница в разделе ПРИМЕРЫ:

[...] Функция fflush() используется, поскольку стандартный вывод обычно буферизуется, и приглашение не может быть немедленно распечатано на выходе или терминале.

Итак, замечание, которое вы добавляете fflush(stdout);, верное.


Альтернативой может быть stdout небуферизованный:

setbuf(stdout, NULL);
/* or */
setvbuf(stdout, NULL, _IONBF, 0);

Но, как отмечает R., вы можете сделать это только один раз, и это должно быть, прежде чем вы напишете на stdout или выполните любое другое действие на нем. (C99 7.19.5.5 2)


Я только что прочитал недавний поток на comp.lang.c примерно то же самое. Одно из замечаний:

Соглашение Unix заключается в том, что stdin и stdout буферизируются по строкам, когда связаны с терминалом, и полностью буферизированы (ака-буферизированы) в противном случае. stderr всегда небуферизован.