Fundamentals 6 min read

How to Build a Real‑Time Console Progress Bar in C

This guide explains the differences between carriage return and newline, explores C output buffering strategies, and provides step‑by‑step C code to create a countdown and a dynamic progress bar that updates smoothly in the terminal.

Liangxu Linux
Liangxu Linux
Liangxu Linux
How to Build a Real‑Time Console Progress Bar in C

Carriage Return vs Newline

In C, \n moves the cursor to the next line and returns to column 0, while \r only returns to the beginning of the current line. Using \n therefore creates a new line; \r can be used to overwrite the current line.

Standard Output Buffering

The C standard library provides three buffering modes for stdout:

Unbuffered : data is written directly to the device.

Line buffered : the buffer is flushed when a newline ( \n) is encountered.

Fully buffered : the buffer is flushed only when it becomes full.

Because stdout is line‑buffered on a terminal, a newline forces an immediate display. Without a newline the output remains in the buffer until the program terminates or the buffer is flushed manually.

#include <stdio.h>
#include <unistd.h>
int main(){
    printf("I am a proc
"); // prints immediately
    sleep(3);
    return 0;
}
#include <stdio.h>
#include <unistd.h>
int main(){
    printf("I am a proc"); // no newline → buffered
    sleep(3);
    return 0;
}

Countdown Example

Using \r after each number returns the cursor to the start of the line, creating a countdown effect. Because the output lacks a newline, fflush(stdout) must be called to force the buffer to the terminal.

#include <stdio.h>
#include <unistd.h>
int main(){
    int count = 3;
    while(count >= 0){
        printf("%d\r", count--);
        fflush(stdout);
        sleep(1);
    }
    return 0;
}

For multi‑digit counts, a width specifier (e.g., %2d) ensures the field occupies a fixed number of characters, preventing leftover digits from remaining on screen.

#include <stdio.h>
#include <unistd.h>
int main(){
    int count = 10;
    while(count >= 0){
        printf("%2d\r", count--);
        fflush(stdout);
        sleep(1);
    }
    return 0;
}

Full Progress Bar Implementation

The program below builds a 100‑character progress bar. It maintains a character array proc, prints the bar with left‑aligned filling using the format "[%-100s] [%d%%]\r", flushes the output, updates the array with ‘#’, and sleeps 100 ms between updates.

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

void ProcBar(){
    int i = 0;
    char proc[102];
    memset(proc, '\0', sizeof(proc));
    while(i <= 100){
        printf("[%-100s] [%d%%]\r", proc, i);
        fflush(stdout);
        proc[i] = '#';
        usleep(100000); // 100 ms
        i++;
    }
    printf("
");
}

int main(){
    ProcBar();
    return 0;
}
Progress bar animation
Progress bar animation
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CBufferingprogress barconsoleprintffflush
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.