Consider this little programm be compiled as application.exe
#include <stdio.h>
int main()
{
char str[100];
printf ("Hello, please type something\n");
scanf("%[^\n]s", &str);
printf("you typed: %s\n", str);
return 0;
}
Now I use this code to start application.exe and fetch its output.
#include <stdio.h>
#include <iostream>
#include <stdexcept>
int main()
{
char buffer[128];
FILE* pipe = popen("application.exe", "r");
while (!feof(pipe)) {
if (fgets(buffer, 128, pipe) != NULL)
printf(buffer);
}
pclose(pipe);
return 0;
}
My problem is that there is no output until I did my input. Then both output lines get fetched.
I can workarround this problem by adding this line after the first printf statement.
fflush(stdout);
Then the first line is fetched before I do my input as expected.
But how can I fetch output of applications that I cannot modify and that do not use fflush() in "realtime" (means before they exit)? .
And how does the windows cmd do it?
The problems of my question in my original post are already very good explained in the other answers.
Console applications use a function named
isatty()to detect if theirstdouthandler is connected to a pipe or a real console. In case of a pipe all output is buffered and flushed in chunks except if you directly callfflush(). In case of a real console the output is unbuffered and gets directly printed to the console output.In Linux you can use
openpty()to create a pseudoterminal and create your process in it. As a result the process will think it runs in a real terminal and uses unbuffered output.Windows seems not to have such an option.
After a lot of digging through winapi documentation I found that this is not true. Actually you can create your own console screen buffer and use it for
stdoutof your process that will be unbuffered then.Sadly this is not a very comfortable solution because there are no event handler and we need to poll for new data. Also at the moment I'm not sure how to handle scrolling when this screen buffer is full.
But even if there are still some problems left I think I have created a very useful (and interesting) starting point for those of you who ever wanted to fetch unbuffered (and unflushed) windows console process output.