
很多刚接触 Linux C 编程的同学,都想做一个能在终端里动态刷新的进度条程序。这不仅能练手 C 语言基础,还能顺便搞懂\r、\n和行缓冲区这些关键概念。今天我们就从零开始,手把手实现一个可运行的进度条程序。
效果图:

一、先搞懂两个核心概念
1. 回车 \r 和换行 \n 的区别
很多人会把这两个搞混,其实它们的起源来自老式打字机:

换行 \n :把打字机的纸往上移动一行,光标留在当前位置的右边。
回车 \r :把打字机的打印头移动到当前行的最开头,不移动纸张。

在终端里,我们要实现进度条的 "原地刷新" 效果,就必须用\r。它会让光标回到行首,这样我们每
次打印新的进度,就会覆盖掉上一次的内容,实现动态更新。
2. 行缓冲区的坑
在 C 语言里,printf默认是行缓冲模式:只有遇到\n换行符,或者程序结束,缓冲区的内容才会被
真正输出到终端。

二、先练手:实现一个倒计时程序

//100秒倒计时
int main()
{
int time = 100;
while (time >= 0)
{
printf("%-3d\r", time);
Sleep(1000);
time--;
}
printf("\n");
return 0;
}
三、正式实现:进度条程序
1.简单实现
1.核心逻辑
进度条会从左到右填充 ,同时右边的百分比和旋转的加载动画也会同步更新,全程都在同一行刷新,体验非常丝滑。

1.核心操作解析
1.buffer:开辟数组
用来进行进度填充、
2.stat:旋转逻辑
3.rate:进度映射
2.业务逻辑
//proce.h
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#define N 101
#define STATE '#'
void process();
void FlushProcess(double total, double current);
void FlushProcess(double total, double current)
{
char buffer[N];
const char* stat="|/-\\";
memset(buffer, 0, sizeof(buffer));
int len=strlen(stat);
int num=(int)(current*100/total);
static int cnt=0;
for(int i=0;i<=num;i++)
{
buffer[i]=STATE;
}
double rate=current/total;
cnt%=len;
printf("[%-100s][%d%%][%c]\r",buffer,(int)(rate*100),stat[cnt]);
cnt++;
fflush(stdout);
}
int main()
{
//process();
double current=0;
while(current<=total)
{
FlushProcess(total,current);
usleep(3000);
current+=speed;
}
printf("\n");
printf("\ndownload %.2lfMB Done\n", current);
return 0;
}