在我们使用printf的时候,我们的数据是先放在缓冲区,然后我们用printf从中拿取,我们可以巧用‘\r’和对缓冲区进行刷新,然后再进行usleep来调整进度条完成的时间,不断打印,来实现动画的效果。
C语言会默认打开三个流,
- 输入流stdin
- 输出流stdout
- 错误信息流stderr
在linux下,C语言以换行‘\n’为标志刷新缓冲区的数据,也就是我们如果没有‘\n’,我们的信息是先放在缓冲区,然后等代码执行完之后刷新缓冲区的数据,我们才在显示屏上看到打印出来的数据,而我们用fflush可以立即刷新缓冲区。
usleep可以让我们看到程序的进行,否则程序运行的速度太快,就看不到动画的效果。
首先,我们可以先尝试刷新缓冲区看到一个动画的效果。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
void processbar()
{
char ch[102];
memset(ch,'\0',sizeof(ch));
int cur = 0;
while(cur <= 100)
{
usleep(50000);
printf("%s\r",ch);
fflush(stdout);
ch[cur++] = '-';
if(cur < 100) ch[cur] = '>';
}
printf("\n");
}
int main()
{
processbar();
return 0;
}
第二,我们可以美化一个我们的进度条的效果,给他加上一些颜色,以及一些小框框
#define RED "\033[0;32;31m"
#define NONE "\033[m"
#define NUM 100
#define SYMBOL '-'
#define LIGHT_PURPLE "\033[1;35m"
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
typedef void (*callback_t)(int);
extern void processbar(int speed);
const char* cur = "|/-\\";
char ch[NUM] = {0};
void processbar(int speed)
{
if(speed > 100 || speed < 0) return;
int len = strlen(cur);
printf(RED "[%-100s]" NONE "[%d%%],[%c]\r",ch,speed,cur[speed%len]);
fflush(stdout);
ch[speed++] = SYMBOL;
if(speed < 100) ch[speed] = '>';
}
void download(callback_t cb)
{
int total = 10000;
int curr = 0;
while(curr <= total)
{
usleep(5000);
int rate = curr*100/total;
cb(rate);
curr += 10;
}
printf("\n");
}
int main()
{
printf(LIGHT_PURPLE "download1:\n" NONE);
download(processbar);
return 0;
}
然后我们编译一下
gcc test.cpp