【Linux】第一个小程序--进度条

这篇具有很好参考价值的文章主要介绍了【Linux】第一个小程序--进度条。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

这篇博客要综合利用以前的知识,来实现一个进度条程序~

目录

换行&回车

缓冲区

实现简单的倒计时

实现进度条

version1

version2


 文章来源地址https://www.toymoban.com/news/detail-838076.html

在开始写这个小程序之前,我们先学习一些预备知识:

换行&回车

【Linux】第一个小程序--进度条,Linux,linux,小程序,运维

缓冲区

【Linux】第一个小程序--进度条,Linux,linux,小程序,运维

【Linux】第一个小程序--进度条,Linux,linux,小程序,运维

 在我们运行这个程序时,并没有直接打印出“hello bit,hello world...”,而是当程序运行结束后才显示出来,但是这并不代表这句打印没有执行,而是没有显示出来而已。

那么,在我sleep期间,字符串在哪里?

答案就是被保存在叫做缓冲区的地方,就是一块内存空间,当程序结束时,一般会自动刷新缓冲区到字符设备(显示器),另外,如果程序遇到‘\n’的时候,也会刷新缓冲区。如果想要强制刷新,可以使用fflush命令。

【Linux】第一个小程序--进度条,Linux,linux,小程序,运维

那么,为什么要有缓冲区呢,为什么按行刷新?为了提高效率,方便人类阅读,人类读信息都是按行读的,是一种尊重用户的表现

 实现简单的倒计时

在实现倒计时中,我们想要达到的效果是依次显示数字,并且下一个覆盖前一个数字,创建test.c文件:

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

我们实现的效果是10,9,...1,0的倒计时效果,其中,

printf("倒计时:%2d\r",cnt);

这句代码中\r是回车,在一次打印完成后,光标回到最前面,继续打印下一个值,覆盖掉上一次的值,用%2d的格式打印的原因是,每次打印两个字符,以防某个字符一直在屏幕上显示。使用fflush(stdout)强制刷新到显示器上。

此外,我们还写了makefile自动化构建工具:

 mycode:test.c
  2   gcc -o $@ $^
  3 .PHONY:clean
  4 clean:
  5   rm -f mycode

至此完成了简单的倒计时效果。

实现进度条

version1

在实现进度条中,我们要创建三个文件:Processbar.h,Processbar.c,Main.c,Main.c负责将Processbar.h中的方法进行调用,最终想达到的效果如下图:

【Linux】第一个小程序--进度条,Linux,linux,小程序,运维

在Processbar.h中,我们定义了Process函数声明;

#pragma once                                                                                                                                 
#include <stdio.h>
extern void Process();

在Processbar.c中实现了Process:

 #include "Processbar.h"
 #include <string.h>
 #include <unistd.h>

 #define Length 101
 #define Style '#'
 const char * label = "|/-\\";
 // version1
  void Process()
  {
     char bar[Length];
     memset(bar,'\0',sizeof(bar));
     int cnt = 0;
     int len =strlen(label);
     while(cnt <= 100)
     {
        printf("[%-100s][%3d%%][%c]\r",bar,cnt,label[cnt%len]);
        fflush(stdout);   
        bar[cnt++]=Style;
        usleep(20000);
     }
       printf("\n");
 }

在上面这段程序中,我们用bar数组来实现进度条,大小Length设为101(包括最后的‘\0’),进度条符号为‘#’。[%-100s]表示字符串靠左对齐,保证了‘#’从左边往右增长。通过循环遍历label所指向的数组来实现旋转光标的效果。

需要注意的是,因为每次使用‘\r’来实现覆盖的效果,但是‘\r’不能让每次结果刷新到显示器上,需要用fflush(stdout)来刷新。usleep()函数的单位是微秒(包含unistd.h头文件)。

在Main.c中,调用Process.h:

#include "Processbar.h"                                                                                                                                                                      
int main()                                                                                  {                                                                                                                                                 
   Process();                                                                                                                                 
   return 0;                                                                                               
}    

最终的实现效果:

【Linux】第一个小程序--进度条,Linux,linux,小程序,运维

version2

上面我们单独写了一个进度条程序,但是,进度条会单独出现吗?肯定不会!它要和具体的场景结合。

假设我们要完成一个下载的场景:下载指定大小的文件,

在Main.c中,我们写出download()这样一个函数:

   double bandwidth = 1024*1024*1.0;                                                                                                                        
   //download
   void download(double filesize,callback_t cb)
   {
     //double filesize = 100*1024*1024*1.0;
     double current = 0.0;
   
     printf("download begin,current:%lf\n",current);
      while(current <= filesize)
     {
        cb(filesize,current);
       //从网络中获取
       current += bandwidth;
       usleep(10000);
      }
      printf("\ndownload done,filesize:%lf\n",filesize);
    }

其中,bandwidth是我们假设的带宽(可以理解为下载速度),download函数的filesize参数是我们要下载的文件大小,第二个参数是进度条打印函数,callback_t是函数指针,其定义在Processbar.h中,

typedef void(*callback_t)(double,double); 

在while循环中,根据filesize和current的大小,打印出当前下载进度的进度条,打印完成后,继续下载,current继续增加,然后再打印下一次的进度条并覆盖之前的进度条。

在Processbar.h中,有如下声明:

#pragma once 
#include <stdio.h> 
typedef void(*callback_t)(double,double);                                                                                                                
void Process(double total,double current);

在Processbar.c中,定义了Process函数:

//version2
void Process(double total,double current)
{
   char bar[Length];
   memset(bar,'\0',sizeof(bar));
   int cnt = 0;
   int len =strlen(label);
 
   double rate = current*100.0/total;
   int loop_count = (int)rate;                                                                                                                            
   while(cnt <= loop_count)
   {
     bar[cnt++]=Style;
   }
   printf("[%-100s][%.1lf%%][%c]\r",bar,rate,label[cnt%len]);
   fflush(stdout);   
 }

根据总文件大小total和当前已下载大小current,打印出当前的进度条,例如,当total=100、current=36时,会打印出如下内容:

【Linux】第一个小程序--进度条,Linux,linux,小程序,运维

在Main.c中,将Process函数作为实参传给download()函数,完成下载。

int main()
{
   download(100*1024*1024,Process);
   download(50*1024*1024,Process);                                                                                                                        
   download(80*1024*1024,Process);
   download(1*1024*1024,Process);
   download(18*1024*1024,Process);
   return 0;
}

 模拟下载了多个文件,其效果如下:

【Linux】第一个小程序--进度条,Linux,linux,小程序,运维

 

到了这里,关于【Linux】第一个小程序--进度条的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux】第一个小程序--进度条

    这篇博客要综合利用以前的知识,来实现一个进度条程序~ 目录 换行回车 缓冲区 实现简单的倒计时 实现进度条 version1 version2   在开始写这个小程序之前,我们先学习一些预备知识:  在我们运行这个程序时,并没有直接打印出“hello bit,hello world...”,而是当程序运行结束后

    2024年03月10日
    浏览(72)
  • 【Linux】编写第一个小程序:进度条

    1.1.1 sleep() 作用:让程序休眠指定秒数,如: sleep(3); //让程序休眠3秒 与 Windows 上的 Sleep() 函数不同 需要包含头文件 unistd.h 1.1.2 fflush() 作用:刷新缓冲区 需要传入一个流 需要包含头文件 stdio.h 1.1.3 usleep() 作用:让程序休眠指定微秒,如: usleep(100000); //让程序休眠100000微秒(

    2024年02月02日
    浏览(32)
  • linux第一个小程序 --- 进度条【简洁】

    结果:先输入hello world然后休眠三秒后结束 当去掉’\\\'n“ 后,结果就变成了先休眠三秒,然后打印hello world后结束。 该现象就证明了缓冲区的存在。 当缓冲区中遇到’‘n’\\\'或者缓冲区被写满后才会被打印出来,在第二张图片里面,没有n,所以hello world先被写入缓存区,然后

    2024年01月20日
    浏览(29)
  • Linux第一个小程序-进度条(c语言版)

    目录 行缓冲区概念: 行缓冲区代码演示: ​编辑进度条代码 1:memset函数: 2:const char* lable=\\\"|/-\\\\\\\";  3:usleep C语言 usleep 函数的功能和用法: 4:进度条代码的实现.c文件与.h文件: ​编辑​编辑5:运行截图 ​编辑进度条代码的实用性优化 优化1:processbar函数内部循环改为

    2024年01月15日
    浏览(38)
  • 【Linux】从0到1实现一个进度条小程序

    个人主页:🍝在肯德基吃麻辣烫 我的gitee:gitee仓库 分享一句喜欢的话:热烈的火焰,冰封在最沉默的火山深处 进度条实现: 本文讲解如何从0到1实现一个进度条小程序。 我们在写作文的时候,写到了一行的结尾,就得另起一行并到开头继续写。 其中,这个另起一行的动作

    2024年02月14日
    浏览(38)
  • 《Linux从练气到飞升》No.07 Linux第一个小程序-进度条的实现

    🕺作者: 主页 我的专栏 C语言从0到1 探秘C++ 数据结构从0到1 探秘Linux 菜鸟刷题集 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇 码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢阅读!!! 前面几章我们讲述了Linux指令、权限管理、编辑器

    2024年02月14日
    浏览(28)
  • 【Linux】:Linux项目自动化构建工具——make/Makefile || Linux第一个小程序——进度条(简单版本)

    在本章开始给大家分享一个图片 希望对你有帮助 在这里插入图片描述 在开始本章之前 我们需要回顾一下上节课的函数的动静态库的优缺点 动态库的优点: 比较节省资源(这里说的资源不仅仅是磁盘资源 也包括网络资源 内存资源等等),不会出现太多的重复代码 缺点:对

    2024年02月05日
    浏览(32)
  • 【Linux】:使用git命令行 || 在github创建项目 || Linux第一个小程序——进度条(进阶版本)

    在本章开始之前还是先给大家分享一张图片 这是C++的笔试题 感兴趣的同学可以去试一试 有难度的哟 也可以直接在牛客网直接搜索这几道题目哈 好了今天我们正式进入我们的正题部分 安装git 使用 Github 创建项目 注册账号 创建项目 ♨️1. 登陆成功后, 进入个人主页, 点击左下

    2024年02月05日
    浏览(40)
  • 【Linux】Linux小程序-进度条

    目录         一、r和n的理解         二、行缓冲区概念         三、进度条源代码 r:回车; n:换行;     那么请问这两个有什么区别呢?     比如:我们在编写内容的时候,一行没有写完的情况下,需要换到下一行的开始位置,此时需要两个步骤:    

    2024年02月06日
    浏览(23)
  • Linux 小程序-进度条

            1.回车换行                 回车换行是两个动作;                 回车是将光标移至当前行的最左侧,                 换行是将当前光标位置移至下一行的相同位置。         2.缓冲区                 由c语言维护的一段内存                  1.stdout:标

    2024年02月10日
    浏览(26)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包