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.
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;
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
