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 }     

效果如下:

相关推荐
YIN_尹18 小时前
【Linux系统编程】进程地址空间
linux·c++
white-persist18 小时前
【vulhub shiro 漏洞复现】vulhub shiro CVE-2016-4437 Shiro反序列化漏洞复现详细分析解释
运维·服务器·网络·python·算法·安全·web安全
代码中介商19 小时前
手把手教你Linux 打包压缩与 gcc 编译详解
linux·运维·服务器·编译·打包·压缩
longerxin202019 小时前
阿里云AlmaLinux操作系统允许root登录配置步骤
linux·服务器·阿里云
独小乐19 小时前
019.ADC转换和子中断|千篇笔记实现嵌入式全栈/裸机篇
linux·c语言·驱动开发·笔记·嵌入式硬件·mcu·arm
HYNuyoah19 小时前
docker 安装win10系统
运维·docker·容器
liulilittle20 小时前
Prompt for OpenCode + CodeX-5.3:多个重型任务交付给AI自动化完成
运维·自动化·prompt
GottdesKrieges20 小时前
OceanBase租户级物理恢复
linux·oceanbase
孙同学_20 小时前
【项目篇】高并发服务器 - HTTP服务器组件拆解,从Util到HttpServer
运维·服务器·http
优雅的大白鹅20 小时前
创建uniapp小程序
小程序·uni-app