1.进度条准备知识
1.1回车与换行
以前的键盘会有一个这样的按键 ,这个键就是回车与换行。
回车:从当前行回退到当前行的起始位置。
换行:从当前行切换到下一行的该位置。
有了以上的认识我们可以写出一个简单的倒计时代码:
注意:在linux下 “\r” 是回车然后在打印。
这样就能在显示行打印出倒计时的感觉了。
1.2缓冲区
先来看一段代码
现象:
命令行先停止了三秒,然后才会出来 hello word。
这是为什么呢?是先执行了sleep(3); 这一行代码吗?
不是的,因为c对io函数提供了一个缓冲区,这段代码执行的结果先被保存在缓冲区中,之后等程序完成后才刷新到屏幕上。
所以有没有什么方法让显示器即刻刷新?有的!通过使用 fflush(stdout) 命令!
这样就能即可在命令行刷新出hello word 无需等待!!!
1.3简单进度条
简单进度条的代码如下:
2.进度条
1.创建makefile文件
2.进度条代码
1.在主函数中调用函数。
2.头文件中定义各种变量
3.
进度条运行过程:
结束:
3.进度条进阶
上面写的进度条并没有根据实际的下载进度来显示进度,而是以固定模式来显示进度。
我们可以根据当前的实际情况来显示进度,比如根据文件的传输速率来显示进度。
代码:
makefile:
1 processbar:main.o processbar.o 2 gcc -o $@ $^3 main.o:main.c4 gcc -c main.c5 processbar.o:processbar.c6 gcc -c processbar.c7 8 .PHONY:clean9 clean:10 rm main.o processbar.o processbar 11
processbar.h
1 #pragma once 2 #include<stdio.h>3 #include<string.h>4 #include<unistd.h>5 6 #define NUM 1027 #define Body '='8 #define Head '>'9 10 void process(); 11 typedef void (*callback_t)(double);12 13 void process_flush( double rate );
processbar.c
#include"processbar.h"2 3 const char *lable = "|/-\\|/-\\";4 5 6 //version17 void process()8 {9 char buffer[NUM];10 memset(buffer , '\0',sizeof(buffer));11 int cnt = 0;12 int n = strlen(lable);13 buffer[0] = Head;14 while(cnt <= 100)15 {16 printf("[%-100s][%3d%%][%c]\r",buffer,cnt,lable[cnt%n]);17 18 fflush(stdout);19 buffer[cnt++] = Body;20 if(cnt < 100) buffer[cnt] = Head;21 usleep(50000);22 23 }24 25 printf("\n");26 27 }1 //version : 进度是多少,你的进度条能知道吗另外,什么进度?依附于其他应用,比如下载32 // 33 char buffer[NUM] = {0};34 void process_flush(double rate)35 {36 37 static int cnt = 0;38 int n = strlen(lable);39 if(rate <= 1.0) buffer[0] = Head;40 41 printf("[%-100s][%.1f%%][%c]\r",buffer,rate,lable[cnt%n]);42 43 fflush(stdout);44 buffer[(int)rate] = Body;45 if((int)rate+1 < 100) buffer[(int)(rate+1)] = Head;46 if(rate>= 100.0) printf("\n");47 48 cnt++;49 cnt %= n;50 }
main.c:
#include<time.h>3 #include<stdlib.h>4 #define FILESIZE 1024*1024*10245 6 void download(callback_t cd)7 {8 srand(time(NULL)^1023);9 int total = FILESIZE;10 while(total)11 {12 usleep(1000);13 int one = rand()%(1024*1024);14 total -= one;15 if(total < 0) total = 0;16 17 //当前的进度是多少?18 int download = FILESIZE - total;19 double rate = (download*1.0 /(FILESIZE))*100.0;20 cd(rate);21 // printf("download: %f\n",rate); //rate有啦,应该让进度条刷新22 23 24 }25 26 27 }int main()34 {35 // process();36 download(process_flush); 37 return 0 ;38 }