Not seeing initial output of printf when I try to rewrite over the same line 5 seconds later

Viewed 99

I'm trying to reproduce from code from Ivor Horton's Beginning C. I couldn't get the results that the code is expecting so I wrote a smaller program with the specific code that I'm having a problem with.

Please see the first for loop. It should print out two random numbers. If I comment out the second for loop which creates an approximate 5 second delay and the subsequent printf("\rHello) I will see the two random numbers. However if I uncomment the second for loop and the subsequent printf, I will never see the two random numbers, only the output Hello, even though the for loop delays the printf("\rHello") for 5 seconds. I thought I would be able to see the two random numbers for at least 4 seconds or so before they are overwritten by the printf("\rHello"). Can anybody tell me what is going on here?

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <time.h>
#include <ctype.h>
#include <stdlib.h>

int main(void) {
    clock_t wait_start = 0;
    time_t seed = 0;
    unsigned int digits = 2;
    unsigned int seconds = 5;
  
    wait_start = clock();
    srand((unsigned int) time(&seed));
    for (unsigned int i = 1; i <= digits; ++i)
        printf("%u ", rand() % 10);
  
    // printf("%Lf\n", ((long double)clock()) / CLOCKS_PER_SEC);
    for (; clock() - wait_start < seconds * CLOCKS_PER_SEC; )
        ;
    // printf("%Lf\n", ((long double)clock()) / CLOCKS_PER_SEC);
    printf("\rHello");
    return 0;
}

The suggested answer is good, if you know what you're looking for. The title of my question is very straight forward literal explanation of what is happening in my code. A beginner may not search for "flush" and "stdout buffer". I didn't search for that and didn't find this solution to my question. It is complementary to the solution to this question to give more understanding to the beginner. The solution to my question gave a straight-forward solution to my question, and then it was followed with more information giving insight as to why I need to use fflush.

1 Answers

The reason the random digits do not appear is you do not flush the stdout stream to the terminal and since you did not output a trailing newline, it is pending in the stream buffer because stdout is usually line buffered by default when attached to a terminal.

Note also that waiting for 5 seconds with a busy loop asking for elapsed CPU time is wasteful. You should instead use a sleep() system call or the equivalent call on the target system (probably _sleep() on Microsoft legacy systems).

Here is a modified version:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

#if defined _WIN32 || defined _WIN64
#include <windows.h>
#else
#include <unistd.h>
#endif

int main(void) {
    int digits = 2;
    int seconds = 5;
  
    srand((unsigned int)time(NULL));
    for (int i = 0; i < digits; i++) {
        printf("%d ", rand() % 10);
    }
    fflush(stdout);

#if defined _WIN32 || defined _WIN64
    Sleep(seconds * 1000UL);
#else
    sleep(seconds);
#endif
    printf("\rHello\n");
    return 0;
}
Related