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

1.缓冲区
#include <stdio.h>
int main()
{
printf("hello bite!");
sleep(2);
return 0;
}

执行此代码后,会 先停顿两秒,再打印出hello bite,但是明明打印在sleep前面,为什么会后打印呢?

因为:

在printf执行完了后,打印的内容被存到了缓冲区
程序快结束时缓存区的内容再打印到显示器
奇妙的事情发生了:

#include <stdio.h>
int main()
{
printf("hello bite!\n");
sleep(3);
return 0;
}

如果我们使用这样的代码,会 先打印出hello bite,再停顿两秒,为啥捏?

可以发现和上面的代码对比多了一个/n

显示器有一种刷新策略,叫 行刷新
而 /n正好代表着换行,所以加了/n的内容会 直接从缓存区打印到显示器上,不用等程序结束
那么我们有没有办法 不用\n也能先打印呢?
包有的:

#include <stdio.h>
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<unistd.h>
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 }

 

推广/合作/学习交流/请大佬加wx
————————————————
版权声明:本文为CSDN博主「hope kc」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/2301_80374809/article/details/145284160

阅读剩余
THE END