Loading... animating dots in C I've recently wanted to make a "Loading..." display in C where the dots print one at a time in order and then reset:



Suprisingly, there isn't much on the internet for doing this well, so I figured I would make a simple program for it.

#include &lt;stdio.h&gt;
#include &lt;time.h&gt;

int main(void)
{
    int msec = 0;
    const int trigger = 500; // ms
    const int printWidth = 4;
    int counter = 0;
    clock_t before = clock();

    while (1)
    {
        fputs("Loading", stdout);
        clock_t difference = clock() - before;
        msec = difference * 1000 / CLOCKS_PER_SEC;
        if (msec &gt;= trigger)
        {
            counter++;
            msec = 0;
            before = clock();
        }
        for (int i = 0; i &lt; counter; ++i)
        {            
            fputc('.', stdout);
        }
        for (int i = 0; i &lt; printWidth - counter; ++i)
        {
            fputc(' ', stdout);
        }
        fputc('\r', stdout);
        fflush(stdout);

        if (counter == printWidth)
        {
            counter = 0;
        }
    }
}


The output given is seen in the .gif above. 

I know this can be done better.  Any suggestions for improvement?
Too frenetic

I ran your program but it was very frenetic.  It was constantly clearing the "Loading" prompt and reprinting it which resulted in a flickering effect.  In addition, the cursor also moved around in a flickery manner (similar to the green box in the animated image).

To improve this, I would do two things:


Don't constantly draw when nothing has changed.  Instead, sleep until the next trigger time and then redraw.  This also has the added benefit of not using 100% of your cpu.  Presumably, you will have another thread running which is doing some loading work, and you don't want this thread to hog cpu time.
You don't need to clear and redraw the whole prompt until you get to the last dot.  Up until that point, you can just draw one dot at a time.


Rewrite

I rewrote your program with the above two fixes in mind:

#include &lt;stdio.h&gt;
#include &lt;unistd.h&gt;

int main(void)
{
    const int trigger = 500; // ms
    const int numDots = 4;
    const char prompt[] = "Loading";

    while (1) {
        // Return and clear with spaces, then return and print prompt.
        printf("\r%*s\r%s", sizeof(prompt) - 1 + numDots, "", prompt);
        fflush(stdout);

        // Print numDots number of dots, one every trigger milliseconds.
        for (int i = 0; i &lt; numDots; i++) {
            usleep(trigger * 1000);
            fputc('.', stdout);
            fflush(stdout);
        }
    }
}


Rewrite 2

In response to the comment where @syb0rg indicated that the main thread should not sleep, here is what I would do in that case:

#include &lt;stdio.h&gt;
#include &lt;time.h&gt;

static void redrawPrompt(void);
static void doWork(void);

int main(void)
{
    const int trigger   = (CLOCKS_PER_SEC * 500) / 1000;  // 500 ms in clocks.
    clock_t   prevClock = clock() - trigger;

    while (1) {
        clock_t curClock = clock();

        if (curClock - prevClock &gt;= trigger) {
            prevClock = curClock;
            redrawPrompt();
        }
        doWork();
    }
}

static void redrawPrompt(void)
{
    static int  numDots;
    const  int  maxDots = 4;
    const  char prompt[] = "Loading";

    // Return and clear with spaces, then return and print prompt.
    printf("\r%*s\r%s", sizeof(prompt) - 1 + maxDots, "", prompt);
    for (int i = 0; i &lt; numDots; i++)
        fputc('.', stdout);
    fflush(stdout);
    if (++numDots &gt; maxDots)
        numDots = 0;
}

static void doWork(void)
{
    // This function does loading work but returns at least every 500 ms.
}