模拟实现Linux中的进度条

发布于:2025-08-29 ⋅ 阅读:(19) ⋅ 点赞:(0)

引言

        模拟实现Linux中的进度条

一、前置知识

回车换行是两个动作:\n = \r + \n

运行这段代码会发现,打印会在sleep3秒后进行,为什么是这样的呢?

  1 #include<stdio.h>                                                                                                                             
  2 #include<unistd.h>
  3 
  4 
  5 int main()
  6 {
  7     printf("hello word");
  8     sleep(3);
  9     return 0;
 10 }

        因为打印函数的内容在缓冲区里面(在内存里面),需要刷新一下屏幕的缓冲区才可以显示出来。

当加上\n时,就可以先打印后sleep3秒。说明屏幕缓冲区的内容是按行刷新的。

        所以可以用fflush函数来手动刷新缓冲区:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 
  4 
  5 int main()
  6 {
  7     printf("hello word");
  8     fflush(stdout);
  9     sleep(3);                                                                                                                                 
 10     return 0;
 11 }

二、先实现一个倒计时程序

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 
  4 
  5 
  6 
  7 int main()
  8 {
  9     int i = 10;
 10     for(; i >= 0; i--)
 11     {
 12         printf("clock:%2d\r",i);                                                                                                              
 13         fflush(stdout);
 14         sleep(1);
 15     }
 16     printf("\n");
 17 
 18     return 0;
 19 }

主要是掌握一下对上面知识的运用。

三、模拟实现进度条

版本1:

process.c文件中:

  1 #include"process.h"
  2 #include<unistd.h>
  3 #include<string.h>
  4 
  5 #define SIZE 101
  6 #define STYLE '='
  7 
  8 
  9 void Process()
 10 {
 11     const char* lable = "|/-\\";
 12     int len = strlen(lable);
 13     char processbuff[SIZE];
 14     memset(processbuff, '\0', sizeof(processbuff));
 15 
 16     int cnt = 0;
 17     while(cnt <= 100)
 18     {
 19         printf("[%-100s] [%d%%][%c]\r", processbuff, cnt, lable[cnt%len]);                                                                    
 20         fflush(stdout);
 21         processbuff[cnt++] = STYLE;
 22         usleep(30000);
 23     }
 24     printf("\n");
 25 
 26 
 27 }

很显然,版本1只是简单模拟了一下进度条,非常不实际,所以实现一个版本2

版本2:

process.h文件中:

  1 #pragma once                                                                                                                                  
  2 #include<stdio.h>
  3 
  4 void Process();
  5 void FlushProcess(double total, double curr);  //更新进度,按照下载进度,更新进度条 
  6 

process.c文件中:

  1 #include"process.h"
  2 #include<unistd.h>
  3 #include<string.h>
  4 
  5 #define SIZE 101
  6 #define STYLE '='
  7 
  8 
  9 void FlushProcess(double total, double curr)  //更新进度,按照下载进度,更新进度条 
 10 {
 11     if(curr > total)
 12         curr = total;
 13     double rate = curr / total * 100;
 14     int cnt = (int)rate;
 15     char processbuff[SIZE];
 16     memset(processbuff, '\0', sizeof(processbuff));
 17     int i = 0;
 18     for(;i < cnt; i++)
 19     {
 20         processbuff[i] = STYLE;
 21     }
 22 
 23     static const char *lable = "|/-\\";
 24     static int index = 0;
 25 
 26     printf("[%-100s][%.1lf%%][%c]\r", processbuff, rate, lable[index++]);
 27     index %= strlen(lable);
 28     fflush(stdout);
 29     if(curr >= total)                                                                                                                         
 30     {
 31         printf("\n");
 32     }
 33 
 34 
 35 
 36 }


main.c文件中:

  1 #include<stdio.h>
  2 #include"process.h"
  3 #include<time.h>
  4 #include<stdlib.h>
  5 #include<unistd.h>
  6 
  7 double gtotal = 1024.0;
  8 double speed = 1.0;
  9 
 10 typedef void (*callback_t)(double, double);
 11 
 12 double SpeedFloat(double start, double range) //模拟不同的速度
 13 {
 14     int int_range = (int)range;
 15     return start + rand()%int_range + (range - int_range);
 16 }
 17 
 18 void Download(int total, callback_t cb )  //模拟下载 
 19 {
 20     srand(time(NULL));
 21     double curr = 0;
 22     while(1)
 23     {
 24         if(curr > total)                                                                                                                      
 25         {
 26             curr = total;  //模拟下载完成
 27             cb(total, curr); //更新进度,按照下载进度,进行更新进度条
 28             break;
 29         }
 30         cb(total, curr);
 31         curr += SpeedFloat(speed, 20.3); //模拟下载行为
 32         usleep(30000);
 33     }
 34 }
 35 
 36 
 37 
 38 int main()
 39 {
 40     printf("download: 20.0MB\n");
 41     Download(20.0, FlushProcess);
 42     printf("download: 2000.0MB\n");
 43     Download(2000.0, FlushProcess);
 44     printf("download: 100.0MB\n");
 45     Download(100.0, FlushProcess);
 46     printf("download: 20000.0MB\n");
 47     Download(20000.0, FlushProcess);
 48 
 49     return 0;
 50 }


运行结果: