My friend gave me a riddle. I run it. but not getting expected output.
Code is:
#include <stdio.h>
#include <unistd.h>
int main()
{
while(1)
{
fprintf(stdout,"hello-out");
fprintf(stderr,"hello-err");
sleep(1);
}
return 0;
}
the output doesn't printing hello-out.
Instead it's printing like this infinitely:
hello-errhello-errhello-errhello-errhello-errhello-errhello-errhello-errhello-errhello-err
Then I tried like this:
#include <stdio.h>
#include <unistd.h>
int main()
{
int i = 0;
while(i <= 5)
{
fprintf(stdout,"hello-out");
fprintf(stderr,"hello-err");
sleep(1);
i++;
}
return 0;
}
the optput is:
hello-errhello-errhello-errhello-errhello-errhello-errhello-outhello-outhello-outhello-outhello-outhello-out
In C language instructions execute line by line. But why it is not following here?
File IO behavior is determined by the system and if you want to keep that order you must explicitly fflush. See this program below:
while(i <= 5)
{
fprintf(stdout,"hello-out");
fflush(stdout);
fprintf(stderr,"hello-err");
fflush(stderr);
sleep(1);
i++;
}
The reason is output buffering.
By default, stdout is buffered: if it's connected to a terminal it's line-buffered, otherwise it's fully-buffered. When it's line-buffered, that means that nothing is printed until you print a newline, the buffer fills up, or the buffer is flushed explicitly. Since you're not printing newlines, the output doesn't show up until the program exits, because all stdio buffers are flushed at that time.
stderr, on the other hand, is not buffered by default. So anything written to it appears immediately.
Related
#include <stdio.h>
#include <wiringPi.h>
#include <softPwm.h>
int main(void)
{
wiringPiSetupGpio();
for(int i = 0 ; i <50; i++)
{
if ( i%10 == 1)
{
printf("\n");
}
printf("%d ", i);
delay(1000);
}
return 0;
}
I'm working in rasberry pi environment.
I want to print a number for each 1 second. But this code did not print a number one by one but
print 10 numbers for each 10 seconds. This code gives 10 numbers in line at once. What's the problem??
The stdout channel is line buffered by default. This means that data sent to stdout won't necessarily appear until a newline character is printed.
If you call fflush(stdout), any buffered output will be immediately printed.
printf("%d ", i);
fflush(stdout);
in order to print the values at the running time using printf you need to add \n so try this may work.
#include <stdio.h>
#include <wiringPi.h>
#include <softPwm.h>
int main(void)
{
wiringPiSetupGpio();
for(int i = 0 ; i <50; i++)
{
if ( i%10 == 1)
{
printf("\n");
}
// a `\n` added at the end of the string!
printf("%d \n", i);
delay(1000);
}
return 0;
}
for more info read this question's answer
The problem is probably that the output stream is not being flushed. I suggest that you call fflush( stdout ); before the delay(1000); function call. This will ensure that all printed data actually becomes observable, before the program enters a wait state.
Normally, it is not necessary to explicitly flush an output stream, because the output will become visible sooner or later. For example, the output buffer will usually get implicitly flushed whenever you read input or when the program ends. Also, if your program is writing output to the user's screen (in contrast to, for example, writing output to a file), then the output stream is probably line-buffered, which means that the output stream will get implicitly flushed whenever a newline character is written.
However, in this case, it appears that the implicit flushing mentioned above is not sufficient. Therefore, you will have to revert to explicit flushing using the function fflush, as mentioned above.
I have a sample program that outputs a line of text every second. In the test program below, this program writes some text to stdout then waits 1 second and repeats 20 times.
I have another program which uses popen (_popen on Windows) to open a pipe for reading from the program. I then use fgets to read data. The problem I have is that the fgets blocks until the program terminates. Then I get all the output, all 20 lines, in one go. I want to get the output a line at a time, then ok for fgets to block until next line ready. The reason is I plan to use this on a program that will be constantly running, outputting text, e.g. like the use of tail.
If I run this code example on a program that outputs some text all in one go and exits then it works fine.
Why does fgets block? The test program does print some text immediately, so why doesn't fgets read this first line of text immediately?
Here is the code:
#include <stdio.h>
#include <windows.h>
void execute(const char* cmd) {
char buffer[128] = { 0 };
FILE* pipe = _popen(cmd, "r");
if (!pipe) {
printf("popen() failed!\n");
return;
}
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != nullptr)
printf("%s", buffer);
}
int rc = _pclose(pipe);
if (rc != EXIT_SUCCESS) { // return code not 0
printf("pclose exit failure: %d\n", rc);
}
}
int main(int argc, char* argv[]) {
if (argc != 2) {
printf("Usage: pipe_test.exe <program>\n");
exit(1);
}
execute(argv[1]);
}
The program run, helloworld.exe:
#include <stdio.h>
#include <windows.h>
int main() {
for (int i = 0; i < 20; i++) {
printf("Hello World %d\n", i);
Sleep(1000);
}
}
Why does fgets block?
Because it's waiting for the children to output something.
The test program does print some text immediately, so why doesn't fgets read this first line of text immediately?
It actually does not print text immediately. The problem here, as #Barmar notices, is that writing to a pipe is buffered (and not line buffered) by the C standard library implementation. This buffering happens in your child program (helloworld), not in your parent program (pipe_test).
From your parent program, you have no control over what the children spawned through popen() will do, therefore if the child output is buffered like in this case, the only thing you can do (without modifying the child's code) is to wait until the buffer is flushed to the pipe.
In order to get the output sooner, you would have to modify the children's code to manually call fflush() or use setvbuf() to disable buffering:
int main() {
setvbuf(stdout, NULL, _IONBF, 0); // Disable buffering on stdout.
for (int i = 0; i < 20; i++) {
printf("Hello World %d\n", i);
Sleep(1000);
}
}
There's really not much else you can do.
I'm trying to make my code print something to the screen, then wait 1 second, then go around the for loop and print it again 21 times. It works when I do this in Windows in CodeBlocks by using #include and then Sleep(1000). But when I'm doing it on my Ubuntu VM by using #include and sleep(1), everything disappears from my terminal for 21 seconds then all appears at once. I think I'm using the wrong function or something.
Any ideas?
This is the code in Ubuntu terminal which ends up removing everything already on my terminal, waits 21 seconds then just prints "Hello" 21 times.
#include <stdio.h>
#include <unistd.h>
int main()
{
for (int i = 0; i < 21; i++)
{
printf("Hello");
sleep(1);
}
}
This is the code in Windows which prints "Hello" every second for 21 seconds therefore printing 21 Hello's on my screen over 21 seconds. Which is what I'm trying to achieve in my Ubuntu VM.
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main() {
for (int i = 0; i < 21; i++)
{
printf("Hello");
Sleep(1000);
}
return 0;
}
In UNIX, process streams buffer - they accumulate I/O and do not "flush" to the underlying device immediately on write, per default. So - you need to flush the stream:
#include <stdio.h>
#include <unistd.h>
int main()
{
for (int i = 0; i < 21; i++)
{
printf("Hello");
fflush(stdout);
sleep(1);
}
}
It would also work if you output a newline '\n' after "Hello", I believe.
printf output is buffered - which means, it is not guaranteed to appear on the screen immediately. Rather, it appears when one of the following happens:
when the buffer becomes full, - at which time the old contents of buffer is displayed to the screen and the buffer is cleared fresh for the new output - this is called buffer flushing
when the application terminates - which forces flushing of all the printf buffers, and this is what you see on the screen
When buffer is flushed by the programmer.
The last case is most interesting for you, and there are two ways you can do this - either include \n (new line) control character in your string, like
printf("Hello\n");
or call fflush for stdout stream, like
printf("Hello");
fflush(stdout);
This program does not terminate nor does it let me input any values, simply a black screen with no output.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int size;
printf("Enter number of elements in array:");
scanf("%d", &size);
printf("\n%d\n", size);
return 0;
}
Sounds like you're suffering from buffering. Add
fflush(stdout);
after the printf line.
By default, if stdout goes to a terminal, it is line buffered, meaning output is only actually written when the buffer is full or when you output a newline (\n). Terminating the program (via exit() or returning from main) closes all open file handles and also forces a flush.
To make sure output is generated right then and there, call fflush.
I was just getting familiar with sleep(), i found that
#include<stdio.h>
int main()
{
int i=0;
printf("*********Testing Sleep***********\n");
for(i=0;i<10;i++)
{
printf("%d",i);
sleep(1);
}
return 0;
}
this does not print number per iteration rather dumps all numbers when gets out of loop....
but when i modify printf...
#include<stdio.h>
int main()
{
int i=0;
printf("*********Testing Sleep***********\n");
for(i=0;i<10;i++)
{
printf("%d\n",i);
sleep(1);
}
return 0;
}
and now as i've added '\n' new line it works as expected... why it is behaving strangely in former one...
This is because the output buffer isn't being flushed (in other words, actually committed to the terminal). When you write a newline, the output buffer is more likely to be (but still not always, in some cases) flushed. Many terminal implementations do this to improve performance. To force the behaviour you want, you need to call fflush(stdout); after each printf call, like this:
#include<stdio.h>
int main()
{
int i=0;
printf("*********Testing Sleep***********\n");
for(i=0;i<10;i++)
{
printf("%d",i);
fflush(stdout);
sleep(1);
}
return 0;
}
What you are looking at is line buffered output. Actually writing to output is an expensive operation, so I/O streams are usually buffered. Actually writing the buffer is deferred until a specific event is encountered. In standard C, you have three types of buffering:
fully buffered - the buffer is written when full.
line buffered - the buffer is written when a newline is encountered (your case).
unbuffered - the buffer is written whenever an I/O function is executed. (Good for error logging.)
Writing the buffer is called flushing. That's why there is a stdio function called fflush(). You might also want to check out setvbuf() and its parameter constants, _IOFBF, _IOLBF and _IONBF. I am sure you can figure out what they mean without looking them up. ;-)
Edit: This program delivers as you originally expected:
#include <stdio.h>
// This is the header where sleep() is declared. Don't go without it.
#include <unistd.h>
int main()
{
int i=0;
// setvbuf() can be called on a stream only BEFORE
// you do any I/O on it!
setvbuf( stdout, NULL, _IONBF, 0 );
printf( "*********Testing Sleep***********\n" );
for ( i = 0; i < 10; ++i )
{
printf( "%d", i );
sleep( 1 );
}
return 0;
}
standard output for terminals is line buffered, output is not written unless there is a newline or you manually flush it.
Output is buffered, so that that the OS has an opportunity to optimize output speed. To make sure they are flushed immediately, do fflush (stdout);, but usually, you don't.
This is because printf() uses buffered output for better performance. Buffer is flushed to the console once \n is printed.
Printf is buffered.
You can force printf to 'flush' its buffer using the fflush call.
Or
Simply push the buffer to stdout using \n as in your case .
More detailed discussion is here