1

I have a C program, where I just wanted to test if I could reproduce a console spinner used in npm install while it installs a module. This particular spinner simply spins in this order:

| / - \

on the same space, so I use the following program:

#include <stdio.h>

int main() {
    char sequence[4] = "|/-\\";

    while(1) {
        for(int i = 0; i < 4; i++) {
            // \b is to make the character print to the same space
            printf("\b%c", sequence[i]);
            // now I want to delay here ~0.25s
        }
    }
}

So I found a way to make it rest for that long from <time.h> documentation and made this program:

#include <stdio.h>
#include <time.h>

void sleep(double seconds) {
    clock_t then;

    then = clock();

    while(((double)(clock() - then) / CLOCKS_PER_SEC) < seconds); //do nothing
}

int main() {
    char sequence[4] = "|/-\\";

    while(1) {
        for(int i = 0; i < 4; i++) {
            printf("\b%c", sequence[i]);
            sleep(0.25);
        }
    }
}

But now nothing prints to the console. Does anyone know how I can go about producing the behavior I want?

EDIT According to what appears to be popular opinion, I've updated my code above to be the following:

#include <stdio.h>
#include <unistd.h>

int main() {
    char sequence[4] = "|/-\\";

    while(1) {
        for(int i = 0; i < 4; i++) {
            printf("\b%c", sequence[i]);
            /* fflush(stdout); */
            // commented out to show same behavior as program above
            usleep(250000); // 250000 microseconds = 0.25 seconds
        }
    }
}
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • 1
    If you want to sleep for a fraction of a second, use `nanosleep()` on POSIX. I suspect windows has a similar function. Don't just redefine the standard `sleep()` function. – EOF Feb 05 '15 at 18:24

3 Answers3

4

You will need to flush after you wrote to the console. Otherwise, the program will buffer your output:

fflush(stdout);
mrks
  • 8,033
  • 1
  • 33
  • 62
1

Things do get printed to console, it's just does not get flushed. Add fflush(stdout) to see the results, or set the console in an unbuffered mode by calling setbuf:

setbuf(stdout, NULL);

A bigger problem with your code is that your sleep method runs a busy loop, which burns CPU cycles for no good reason. A better alternative would be to call usleep, which takes the number of microseconds:

usleep(25000);
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • ``usleep`` requires ```` which is platform dependent. That's why I used ```` -- it's standard – Patrick Roberts Feb 05 '15 at 18:24
  • @PatrickRoberts But that requires a busy loop, which is really wasteful. That's a thing to avoid if you can, even at the expense of introducing a system-dependent conditional compile block. – Sergey Kalinichenko Feb 05 '15 at 18:26
  • @dasblinkenlight Most implementations of `sleep` that I've ever seen on Linux do not busy loop. They put the process to sleep with a suitable wakeup timer set... Of course the OP didn't state a platform, so it's possible there's some truth to your thinking that `sleep` busy-waits... That would be pretty non-optimal, though, as you point out. – twalberg Feb 05 '15 at 18:27
  • @twalberg I am talking about OP's way of implementing it (see the second code snippet). – Sergey Kalinichenko Feb 05 '15 at 18:29
  • 1
    Ah... completely missed that OP was redefining `sleep`... That is bad for more reasons than just the busy loop one... – twalberg Feb 05 '15 at 18:30
1

The sleep function isn't really your problem. The issue is that the output is buffered. The simplest thing to do will be to research ncurses.

For now:

fflush(stdout);
David Hoelzer
  • 15,862
  • 4
  • 48
  • 67