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 }     

效果如下:

相关推荐
未济3 天前
linux 配置环境变量
linux
傲世仙尊3 天前
目录即文件-Ext文件系统收尾篇
linux·c语言
虎头金猫3 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
_艾伦 耶格尔.3 天前
进程间通信
linux
AI职业加油站3 天前
AI智能体应用工程师证书:政策红利下的职业新风口
大数据·运维·人工智能·学习·职场发展
Liuqy-053 天前
Linux IO编程——静态库、动态库
linux
此冬歌咏3 天前
K8s 节点故障实战:优雅驱逐 31 秒,硬故障 331 秒,以及那个永远 Pending 的 Pod
运维·k8s
MoonMoonLee3 天前
小程序配置
小程序
彧azz3 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
-梅3 天前
linux(8) 软硬链接
linux·运维·服务器