Почему printf не сбрасывается после вызова, если новая строка не находится в строке формата?
почему printf
Не смывать после вызова, если новая строка не находится в строке формата? Это поведение POSIX? Как я мог printf
немедленно смывать каждый раз?
9 ответов:
The
stdout
поток буферизуется, поэтому будет отображаться только то, что находится в буфере после того, как он достигнет новой строки (или когда ему будет сказано). У вас есть несколько вариантов для печати сразу:печать в stderr вместо использования
fprintf
:fprintf(stderr, "I will be printed immediately");
Flush stdout всякий раз, когда вам это нужно с помощью
fflush
:printf("Buffered, will be flushed"); fflush(stdout); // Will now print everything in the stdout buffer
Edit: из комментария Энди Росса ниже, вы также можете отключить буферизацию на stdout с помощью
setbuf
:setbuf(stdout, NULL);
нет, это не поведение POSIX, это поведение ISO (ну, это и поведение POSIX, но только в той мере, в какой они соответствуют ISO).
стандартный вывод буферизуется линией, если он может быть обнаружен для ссылки на интерактивное устройство, в противном случае он полностью буферизован. Так что бывают ситуации, когда
printf
не смыть, даже если он получает новую строку для отправки, например:myprog >myfile.txt
это имеет смысл для эффективности, так как, если вы взаимодействуете с пользователем, они наверное, хотят видеть каждую строчку. Если вы отправляете вывод в файл, скорее всего, на другом конце нет пользователя (хотя это не невозможно, они могут следить за файлом). Теперь ты может утверждают, что пользователь хочет видеть каждый символ, но есть две проблемы с этим.
во-первых, это не очень эффективно. Во-вторых, первоначальный мандат ANSI C должен был в первую очередь кодифицировать существующей поведение, а не выдумывать новая поведение, и эти проектные решения были приняты задолго до того, как ANSI начал процесс. Даже ISO в настоящее время действует очень осторожно при изменении существующих правил в стандартах.
как с этим бороться, если вы
fflush (stdout)
после каждого выходного вызова, который вы хотите увидеть немедленно, это решит проблему.кроме того, вы можете использовать
setvbuf
перед началом работы наstdout
, чтобы установить его в unbuffered, и вам не придется беспокоиться о добавлении все этиfflush
строки вашего кода:setvbuf (stdout, NULL, _IONBF, BUFSIZ);
просто имейте в виду, что может повлиять на производительность совсем немного, если вы are отправка выходных данных в файл. Также имейте в виду, что поддержка этого определяется реализацией, а не гарантируется стандартом.
раздел ISO C99
7.19.3/3
соответствующий бит:когда поток unbuffered, символы должны появляться из источника или в месте назначения как можно скорее. В противном случае символы могут накапливаться и передаваться в среду хоста или из нее в виде блока.
когда поток полностью буферизованной, символы предназначены для передачи В или из среды хоста в виде блока при заполнении буфера.
когда поток линия буферизованный, символы предназначены для передачи В или из среды хоста в виде блока, когда символ новой строки встречающийся.
поддержка этих характеристик определяется реализацией и может быть затронута через
setbuf
иsetvbuf
функции.
это, вероятно, так из-за эффективности и потому, что если у вас есть несколько программ, пишущих в один TTY, таким образом, вы не получаете символы на линии чересстрочной. Поэтому, если программа A и B выводятся, вы обычно получаете:
program A output program B output program B output program A output program B output
это воняет, но это лучше, чем
proprogrgraam m AB ououtputputt prproogrgram amB A ououtputtput program B output
обратите внимание, что даже не гарантируется сброс на новой строке, поэтому вы должны сбросить явно, если промывка имеет значение для вас.
Примечание: библиотеки Microsoft runtime не поддерживают буферизацию строк, поэтому
printf("will print immediatelly to terminal")
:
stdout буферизуется, поэтому будет выводиться только после печати новой строки.
получить немедленный вывод, либо:
- печать в stderr.
- сделать stdout без буфера.
по умолчанию, стандартный вывод буферизируется построчно, поток stderr нет буферизованная и файл полностью амортизированный.