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

1.缓冲区

cpp 复制代码
#include <stdio.h>
int main()
{
 printf("hello bite!");
 sleep(2);
 return 0;
}

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

因为:

  • 在printf执行完了后,打印的内容被存到了缓冲区
  • 程序快结束时缓存区的内容再打印到显示器

奇妙的事情发生了:

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

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

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

  • 显示器有一种刷新策略,叫 行刷新
  • /n正好代表着换行 ,所以加了/n的内容会 直接从缓存区打印到显示器上不用等程序结束

那么我们有没有办法 不用\n也能先打印呢?

包有的:

cpp 复制代码
#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(重点)

cpp 复制代码
#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(重点)

cpp 复制代码
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(重点)

cpp 复制代码
#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 }     

效果如下:

相关推荐
AGI学习社9 分钟前
2024中国排名前十AI大模型进展、应用案例与发展趋势
linux·服务器·人工智能·华为·llama
H.2029 分钟前
centos7执行yum操作时报错Could not retrieve mirrorlist http://mirrorlist.centos.org解决
linux·centos
wanhengidc43 分钟前
网站服务器中的文件被自动删除的原因
运维·服务器
9毫米的幻想1 小时前
【Linux系统】—— 编译器 gcc/g++ 的使用
linux·运维·服务器·c语言·c++
helloliyh1 小时前
Windows和Linux系统安装东方通
linux·运维·windows
LilySesy2 小时前
【业务案例】F.13——SAP系统标准的清帐程序有BUG?
运维·bug·sap·abap·esb·internet服务
张某人想退休2 小时前
自动化实现的思路变化
运维·自动化
秋风&萧瑟3 小时前
【数据结构】顺序队列与链式队列
linux·数据结构·windows
我科绝伦(Huanhuan Zhou)3 小时前
Linux 系统服务开机自启动指导手册
java·linux·服务器