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.c
4 gcc -c main.c
5 processbar.o:processbar.c
6 gcc -c processbar.c
7
8 .PHONY:clean
9 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 102
7 #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 //version1
7 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*1024
5
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 }