> 技术文档 > Linux探秘坊-------4.进度条小程序

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

Linux探秘坊-------4.进度条小程序

2.main.c

Linux探秘坊-------4.进度条小程序

3.process.c(重点)

Linux探秘坊-------4.进度条小程序

#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

Linux探秘坊-------4.进度条小程序

2.process.c(重点)

Linux探秘坊-------4.进度条小程序

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(重点)

Linux探秘坊-------4.进度条小程序

#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 } 

效果如下:
Linux探秘坊-------4.进度条小程序