一、预期效果
执行程序后,屏幕上会出现一个动态更新的进度条。该进度条从0%开始,随着时间递增而逐步填充,直到完全填满,最终效果如图所示
二、基础知识
1. \n
\n(换行符,Line Feed) :使光标移动到下一行(垂直移动)
cpp
printf("Hello\nWorld");
// 输出:
// Hello
// World
2. \r
\r(回车符,Carriage Return) :使光标移动到当前行的开头(水平移动)
cpp
printf("Loading...\rDone!");
// 输出:Done!...
// (光标回到行首,"Done!"覆盖了"Loading...")
3. fflush(stout);
fflush(stdout) 用于强制刷新标准输出缓冲区,将缓冲区中的数据立即写入终端或文件。
cpp
#include <stdio.h>
#include <unistd.h>
int main() {
// 情况1:没有 fflush
printf("Loading...");
sleep(2); // 等待2秒后才显示
printf(" Done!\n");
// 情况2:使用 fflush
printf("Processing...");
fflush(stdout); // 立即显示
sleep(2);
printf(" Complete!\n");
return 0;
}
三、代码段
1. 头文件和变量声明
cpp
#include <stdio.h> // 标准输入输出,用于printf
#include <string.h> // 字符串操作,用于memset
#include <unistd.h> // Unix标准函数,用于usleep
int main()
{
int i = 0; // 进度计数器(0-100)
char bar[101]; // 进度条显示数组,101个字符(100个填充+1个'\0')
memset(bar, 0, sizeof(bar)); // 将bar数组全部初始化为0(空字符)
char lable[4] = {'|', '/', '\\', '-'}; // 旋转动画符号数组
// 注意:'\\'表示反斜杠,需要转义
2. 进度条显示逻辑
cpp
while(i <= 100) // 循环101次(从0到100)
{
// 关键输出语句
printf("[%-100s][%3d%%][%c]\r", bar, i, lable[i%4]);
// 各部分解释:
// [%-100s] - 左对齐、宽度100的字符串(进度条主体)
// [%3d%%] - 宽度3的整数,显示百分比(如" 0%", " 50%", "100%")
// [%c] - 单个字符,显示旋转动画
// \r - 回车符,光标回到行首(实现原地更新)
fflush(stdout); // 强制刷新输出缓冲区,立即显示
bar[i++] = '='; // 在当前进度位置添加'='字符,然后i自增
usleep(50000); // 暂停50000微秒(0.05秒),控制动画速度
}
3. 关键技术点详解
🎯 原地更新的魔法:\r的作用
普通换行用
\n,光标移动到下一行开头回车符
\r将光标移回当前行开头下一次
printf会覆盖上一次的内容实现效果:进度条在同一行动态变化,而不是打印多行
🔄 旋转动画的实现
cpp
char lable[4] = {'|', '/', '\\', '-'};
// 循环显示:| → / → \ → - → | ...
// i%4 获取0-3的循环索引:0,1,2,3,0,1,2,3...
⏱️ 时间控制
cpp
usleep(50000); // 50000微秒 = 0.05秒
📊 进度条格式控制
cpp
printf("[%-100s][%3d%%][%c]\r", bar, i, lable[i%4]);
%-100s:左对齐,宽度100字符
%3d%%:宽度3,显示整数,%%转义为百分号%进度条结构:
[进度条][百分比][动画符号]
4. 运行时的视觉变化
cpp
初始状态:[][ 0%][|]
1%时: [=][ 1%][/]
50%时: [==================================================][ 50%][|]
100%时: [====================================================================================================][100%][-]
5.完整代码
cpp
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
int i = 0;
char bar[101];
memset(bar,0,sizeof(bar));
char lable[4] = {'|','/','\\','-'};
while(i<=100)
{
printf("[%-100s][%3d%%][%c]\r",bar,i,lable[i%4]);
fflush(stdout);
bar[i++] = '=';
usleep(50000);
}
printf("\n");
return 0;
}
