Question

What I'm trying to do is have the terminal print out a string, pause, and then write over that string. What's happening though is that the program simply prints out the final result, without ever showing the first string.

I thought I could use sleep to do this, but it doesn't work. Why not?

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

int main(void){

    char message[] = "Hello there";
    int messageLength = sizeof(message);
    int i;

    printf("Hello, Dave.");
    sleep(2);
    for(i = 0; i < messageLength; i++)
        printf("\b");
    printf("Anyone there?\n");

    return 0;

}

Updated version, thanks to answers:

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

void twprint(char* output, int outputLength, struct timespec* delay);
void twbackspace(int length, struct timespec* delay);

int main(void){

    char message1[] = "Hello, Dave.";
    char message2[] = "Are you there, Dave?";
    char message3[] = "I heard you talking in the pod.";
    char message4[] = "Dave?";
    struct timespec duration = { .tv_sec = 0, .tv_nsec = (100 * 1000 * 1000) }; 
    /* ^ .tv_nsec = one hundred million nanoseconds */

    twprint(message1, sizeof(message1)/sizeof(char), &duration);
    sleep(2);
    twbackspace(sizeof(message1)/sizeof(char), &duration);

    twprint(message2, sizeof(message2)/sizeof(char), &duration);
    sleep(2);
    twbackspace(sizeof(message2)/sizeof(char), &duration);

    twprint(message3, sizeof(message3)/sizeof(char), &duration);
    sleep(2);
    twbackspace(sizeof(message3)/sizeof(char), &duration);

    sleep(2);
    duration.tv_nsec *= 5;
    twprint(message4, sizeof(message4)/sizeof(char), &duration);

    printf("\n");

    return 0;

}

void twprint(char* output, int outputLength, struct timespec* delay){

    int i;
    struct timespec remaining; /* dummy parameter */

    for(i = 0; i < outputLength; i++){
        printf("%c", output[i]);
        fflush(stdout);
        nanosleep(delay, &remaining);
    }

}

void twbackspace(int length, struct timespec* delay){

    int i;
    struct timespec remaining; /* dummy parameter */

    for(i = 0; i < length; i++){
        printf("\b \b");
        fflush(stdout);
        nanosleep(delay, &remaining);
    }
}
Was it helpful?

Solution

The output of printf is buffered and won't be printed to the console until the buffer is full, you print a newline, or call fflush(stdout). Try:

...
printf("Hello, Dave.");
fflush(stdout);
sleep(2);
...

Wikipedia provides a good explanation of standard streams and their behavior with respect to buffering.

OTHER TIPS

You need to flush the output stream to get the line to show up:

printf("Hello, Dave.");
fflush(stdout);

Normally, console output would go to stderr, by the way. If you did that, you wouldn't have to worry about flushing (on many platforms) because stderr is typically unbuffered (so output is immediate), whereas stdout is typically line-buffered (so output doesn't show up until you write a newline character).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top