2
\$\begingroup\$

Okay I've just finished writing a nice tiny C program to have an ASCII spinner (works on Windows and POSIX). I'm quite new to C, so any suggestions would be great. This is designed to be a small function in my other programs, so please point out anything that could cause problems when been integrated into a larger program.

The only part I am not 100% sure about is how I handle the standard output buffer when it's printed the next character in the cycle. I don't want the buffer to fill up with invisible backspace characters, so is using fflush on stdout the best way?

#ifdef _WIN32
    #include <windows.h>
    #define sleepThr(x) Sleep(x)
#else
    #include <unistd.h>
    #define sleepThr(x) usleep((x) * 1000)
#endif

#include <stdio.h>

#define INTERVAL 200

int main()
{
    int counter = 0;

    while (1)
    {
        switch (counter)
        {
            case 0:
                printf("\b|");
                break;

            case 1:
                printf("\b/");
                break;

            case 2:
                printf("\b-");
                break;

            case 3:
                printf("\b\\");
                counter = -1;
                break;
        }

        fflush(stdout);

        sleepThr(INTERVAL);

        counter++;
    }

    return 0;
}
\$\endgroup\$
2
\$\begingroup\$

Using fflush is pretty much required as output would otherwise be buffered until a newline character is printed.

You could use counter as an index to a character array instead of a big clunky repetitive switch. If you have a char *spinner = "|/-\\";, spinner[0] will be "|", spinner[1] will be "/", etc.

char *spinner = "|/-\\"; printf("\b%c", spinner[counter]); is going to print the common backspace character and the correct "spinner symbol" for each value of counter. The spinner variable does not need to be declared because it's a string literal: printf("%c", "|/-\\"[counter]); can be used instead.

Apart from the unnecessary switch, I'd say you have an excessive amount of blank lines. If they are used more scarcely, their relative effect will be greater. Readability becomes more important as the program gets bigger.

/*
 * Separated groups of code:
 * If there were empty lines between all statements, it would be
 * difficult to tell the groups apart.
 */

foo(bar->baz);
foo(bar->quux);

counter++;
counter %= 4;

Here's a modified version:

#ifdef _WIN32
    #include <windows.h>
    #define sleepThr(x) Sleep(x)
#else
    #include <unistd.h>
    #define sleepThr(x) usleep((x) * 1000)
#endif

#include <stdio.h>

#define INTERVAL 200

int main()
{
    int counter;
    while (1)
    {
        for (counter = 0; counter < 4; counter++)
        {
            printf("\b%c", "|/-\\"[counter]);
            fflush(stdout);
            sleepThr(INTERVAL);
        }
    }

    return 0;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.