Flushing output buffer in C (cgi) - c

The following code:
int z = 0;
while(z < 4)
{
printf("iteration %d\n",z);
sleep(1);
z++;
}
Works fine and stdout buffer is flushed every second if running the program from command line. However, when I try to access the program in a web browser (server - apache on linux, compiled executable (with gcc) handled through cgi), the content is displayed only after 4 seconds and not "step by step". I am looking for something like PHP's ob_flush(). And, by the way, is cgi the best way of processing compiled C executables?
Update: neither fflush(stdout) nor setvbuf(stdout, NULL, _IONBF, 0) is working!!! Works great after disabling mod_deflate.

I am not quite sure I understand your question correctly, but in C you can
Flush after each print (fflush)
Disable buffering (setbuf, setvbuf)
setvbuf(stdout, NULL, _IONBF, 0); /* this will disable buffering for stdout */
If these won't work, then either something else is doing buffering or buffering is not the problem.

You could try to fflush stdout after your printf.

Related

C: printf still not flushing before while loop, even with new line character in format string [duplicate]

This question already has answers here:
What are the rules of automatic stdout buffer flushing in C?
(5 answers)
Is stdout line buffered, unbuffered or indeterminate by default?
(1 answer)
Closed 3 years ago.
I have read many questions with people asking why printf did not work before a while loop; the answer was that it was not flushing stdout because they did not have a new line character in their format string. However, the following simple code is still not producing output for me:
#include <stdio.h>
int main() {
printf("Hello world!\n");
while (1);
return 0;
}
However, adding fflush(stdout); after the printf call produces output. The new line character is supposed to make this unnecessary, so why does it not work without it?
It's quite common for stdout to be line-buffered when connected to a terminal (flushed on line feed), and block-buffered otherwise (flushed when buffer is full).
For example,
#include <stdio.h>
#include <unistd.h>
int main(void) {
printf("foo\n");
sleep(5);
return 0;
}
Test:
$ ./a
foo
[5s pause]
$ ./a | cat
[5s pause]
foo
(gcc on Linux)
I'm using mingw with Eclipse on Windows.
It seems that Eclipse is connecting the stdout of your program to a pipe so it can collect the output and display it in its window. Your program thus uses block buffering for stdout.
A very good answer by #schot here.
He said :
The C99 standard does not specify if the three standard streams are unbuffered or line buffered: It is up to the implementation. All UNIX implementations I know have a line buffered stdin. On Linux, stdout is line buffered and stderr unbuffered.
One way to be sure that your line(s) will be printed directly is making stdout unbuffered:
setbuf(stdout, NULL);
/* or */
setvbuf(stdout, NULL, _IONBF, 0);
But you can only do this once, and it must be before you write to stdout or perform any other operantion on it. (C99 7.19.5.5 2)
Additional Info :
Shouldn't a new line character flush the output?
-It depends, if the output device is determined to be interactive (e.g. a terminal) the newline flush the buffer. Otherwise new line(s) don't flush the buffer.
What constitutes an interactive device is implementation-defined (C99 section 5.1.2.3/6) 

Clion doesn't print to console

I am using printf("%d", 15); and nothing prints on the console.
I tried calling setvbuf (stdout, NULL, _IONBF, 0); first, nothing changed.
Any ideas how to tackle this issue ?
printf buffers the output. It will not flush the buffer (i.e. actually write out the contents) until a newline is reached.
The best remedy is to use printf("%d\n", 15);. Alternatively you can flush the buffer using fflush(stdout);
You can suppress the buffering behaviour by writing setbuf(stdout, NULL); but I wouldn't recommend your interfering with the workings in that way.

Printf not working with scanf

Hi i am new to the programing and for example in my code:
#include <stdio.h>
int main (void){
int a;
printf("Write a number: ");
scanf("%d", &a);
printf("Your written number was: %d", a);
return 0;
}
Printf does not write "write a number" in console when i start the program but only after i already inserted the number and pressed enter.
I have already done some research and found out for this code:
setvbuf(stdout, NULL, _IONBF, 0);
when i paste this into my program it works as it should but i am wondering why do i have to do that?
when i paste this into my program it works as it should but i am
wondering why do i have to do that?
It's because printf() is usually line-buffered when attached to a terminal. So disabling the buffering with the call to setvbuf() makes stdio library to not buffer at all.
You can also use fflush(stdout); after the printf() call to flush out the buffered output. The same can be done with setbuf(stdout, NULL); as well.
You can also add a \n at the end of printf() statement to force the flushing. But this will work only if the output goes to a terminal device.
For example, if you do (on a unix-like system):
./a.out > output_file
then the \n will not flush the buffer.
Out of the two options (setbuf() and fflush()),fflush(stdout); is probably the better option in most cases. Since disabling the buffering completely can have negative impact on performance (which is the primary reason for buffering in the first place) whereas fflush() can be judiciously used at the right place when you think it's necessary.
printf has a buffer. It is a mechanism to make code run faster by not having to switch between the user context and the kernel context. To get over this you can tell the code to flush the buffer - i.e. send it to the operating system. This can be done by
fflush(stdout);
After a printf. If the printf contains a new line this is done automatically.
You probably want \n in each of those printf statements.
Add linefeed "\n" to your printf lines like so:
printf("Write a number: \n");

why doesn't this c programme print the first printf statement?

#include<stdio.h>
#include <unistd.h>
int main(){
while(1)
{
fprintf(stdout,"hello-out");
fprintf(stderr,"hello-err");
sleep(1);
}
return 0;
}
On compiling this programme in gcc and on executing it only prints hello-err and not hello-out.Why is that so?Can someone please explain the reason behind it?
If you add a '\n' to your message it will (or should), ie. "hello-out\n".
The reason being is that stdout is buffered in order to be more efficient, whereas stderr doesn't buffer it's output and is more appropriate for error messages and things that need to be printed immediately.
stdout will usually be flushed when:
A newline (\n) is to be printed
You read in from stdin
fflush() is called on it
EDIT: The other thing I wanted to add before my computer crashed...twice...was that you can also use setbuf(stdout, NULL); to disable buffering of stdout. I've done that before when I've had to use write() (Unix) and didn't want my output to be buffered.
It doesn't always print out the output to stdout because by design stdout is BUFFERED output, and stderr is unbuffered. In general, the for a buffered output stream, the stream is not dumped until the system is "free" to do so. So data can continue buffering for a long while, before it gets flushed. If you want to force the buffer to flush you can do so by hand using 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;
}
Update: stdout is linebuffered when connected to a terminal, and simply buffered otherwise (e.g. a redirect or a pipe)
You forgot newlines (noted \n) in your strings. Or you need to call fflush(NULL); or at least fflush(stdout); before sleep(1);
And fprintf(stdout, ...) is the same as printf(...)
You need to output newlines or to call fflush because (at least on Linux) the stdout FILE buffer is line-buffered. This means that the C library is buffering data, and will really output it (using the write Linux system call) when the buffer is full enough, or when you flush it either with a new line, or by calling fflush. Buffering is needed because system calls are costly (calling write for every byte to be output is really too slow). Read also the man page of setbuf

Why does printf() not print anything before sleep()?

I'm just learning C with Kernighan and Ritchie's book; I'm in the basics of the fourth chapter ("Functions and Program Structure"). The other day I became curious about the sleep() function, so tried to use it like this:
#include <stdio.h>
#include <unistd.h>
int main(void)
{
printf(" I like cows.");
sleep(5);
return 0;
}
The problem is the output of the program, it looks like it does the sleep() first and then the printf(), in other words, it waits five seconds and then prints the string. So I thought, maybe the program gets to sleep() so fast that it doesn't let printf() have his work done like I want, that is print the string and then sleep.
How can I show the string and then put the program to sleep?
The compiler is GCC 3.3.5 (propolice) in OpenBSD 4.3.
printf() writes to stdout (the default output stream) which is usually line buffered. The buffer isn't flushed by the time sleep is called so nothing is displayed, when the program exits all streams are automatically flushed which is why it prints right before exiting. Printing a newline will usually cause the stream to be flushed, alternatively you could use the fflush function:
int main(void)
{
printf(" I like cows.\n");
sleep(5);
return 0;
}
or:
int main(void)
{
printf(" I like cows.");
fflush(stdout);
sleep(5);
return 0;
}
If you are printing to a stream that is not line buffered, as may be the case if stdout is redirected or you are writing to a file, simply printing a newline probably won't work. In such cases you should use fflush if you want the data written immediately.
Your problem is that printf (and anything else that uses the stdio library to write to stdout (standard output)) is buffered - line buffered if it goes to the console, and size buffered if it goes to a file. If you do a fflush(stdout); after the printf, it will do what you want. You could try just adding a newline ('\n') to your string, and that would do the right thing as long as you don't redirect standard output to a file.
I'm not 100% sure, but I think stderr isn't buffered, which can cause confusion because you might see output you made to stderr before output you previously made to stdout.
Buffering means that all the output is stored in a place (called buffer) and is output after a certain amount of data is present in it. This is done for efficiency reasons.
Some (most?) implementations clear the buffer after a newline when writing to the console, so you can also try
printf(" I like cows.\n");
instead of the call to fflush()
I implemented time encounter as following;
for (int i = 1; i <= 60; i++) {
printf("%02d", i);
fflush(stdout);
sleep(1);
printf("\b\b");
}

Resources