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);
    }
}
 
    