Linux探秘坊-------4.进度条小程序
1.缓冲区
#include int main(){ printf(\"hello bite!\"); sleep(2); return 0;}
执行此代码后,会 先停顿两秒,再打印出hello bite
,但是明明打印在sleep前面,为什么会后打印呢?
因为:
- 在printf执行完了后,打印的内容被存到了缓冲区
- 程序快结束时缓存区的内容再打印到显示器
奇妙的事情发生了:
#include int main(){ printf(\"hello bite!\\n\"); sleep(3); return 0;}
如果我们使用这样的代码,会 先打印出hello bite,再停顿两秒
,为啥捏?
可以发现和上面的代码对比多了一个/n
- 显示器有一种刷新策略,叫
行刷新
- 而
/n正好代表着换行
,所以加了/n的内容会直接从缓存区打印到显示器上
,不用等程序结束
那么我们有没有办法 不用\\n也能先打印呢?
包有的:
#include int main(){ printf(\"hello bite!\"); fflush(stdout); sleep(3); return 0;}
- 这里的fflush(stdout)就起到了
刷新的作用
2.进度条(V1)
1.process.h
2.main.c
3.process.c(重点)
#include\"process.h\" 2 #include<string.h> 3 #include<unistd.h> 4 5 #define size 101//需要考虑\\0所以不是100 6 #define style \'#\' 7 8 void process() 9 { 10 int rate =0; 11 char num[size]; 12 memset(num,0,sizeof(num));//这里是让num全部置空W> 13 char* lable=\"|/-\\\\\";//这里是模拟进度条后的圈圈 14 int length=strlen(lable); 15 while(rate<=100) 16 { 17 printf(\"[%-100s][%d%%][%c]\\r\",num,rate,lable[rate%length]);//100s是指预留100个字符,主要是为让】不动,但这样会导致倒着打印,所以需要加-, \\r是指每次打印完了之后都恢复到原位置 18 fflush(stdout);//这里因为没有\\n所以需要fflush进行刷新 19 num[rate]=style; 20 ++rate; 21 usleep(50000);//usleep和sleep不同,前者单位是微秒 50000微秒=0.5秒 22 } 23 24 printf(\"\\n\"); 25 }
3.进度条(V2)
1.process.h
2.process.c(重点)
void flushprocess(const char*tips, double total,double current) 29 { 30 const char *lable=\"|/-\\\\\"; 31 int len =strlen(lable); 32 static int index=0; 33 char num[size]; 34 memset(num,0,sizeof(num));//将num置空 35 36 double rate=current*100.0/total;//计算下载进度 37 int n=(int)rate;//用下载进度确定有多少个# 38 39 int i=0; 40 for(;i<n;i++) 41 num[i]=style;//填充#到num中 42 43 printf(\"%s...[%-100s][%.1lf%%][%c]\\r\",tips,num,rate,lable[index++]);//进度保留一位小数 44 fflush(stdout);//因为没有使用\\n,却又想直接刷新,所以需要fflush,记得包头文件#include 45 index %=len; 46 if(n>=100)printf(\"\\n\"); 47 }
3.main.c(重点)
#include\"process.h\" 3 #include<unistd.h> 4 #include<time.h> 5 #include<stdlib.h> 6 7 typedef void (*call)(const char*, double,double);//定义函数指针类型 8 9 10 11 double speed[]={5.0,0.5,0.3,0.02,0.1,0.01};//模拟网速的波动 12 13 void download(int total,call cb) 14 { 15 srand(time(NULL));//设置种子 16 double current =0.0; 17 while(current<=total) 18 { 19 cb(\"下载中 \",total,current); 20 if(current>=total)break; 21 int random=rand()%6;//随机匹配网速 22 usleep(5000); 23 current+=speed[random];//加上每次下载的进度 24 if(current>=total)current=total;//有可能总和超过total,这样就没法显示100%,所以需要改为total 25 } 26 } 27 28 29 30 31 int main() 32 { 33 download(1024.0,flushprocess);//传递文件大小和函数地址 34 printf(\"下载 1024.0MB 完成\\n\"); 35 download(512.0,flushprocess); 36 printf(\"下载 512.0MB 完成\\n\"); 37 download(256.0,flushprocess); 38 printf(\"下载 256.0MB 完成\\n\"); 39 download(128.0,flushprocess); 40 printf(\"下载 128.0MB 完成\\n\"); 41 42 return 0; 43 }
效果如下: