如何在Linux下打印出进度条


一、引言

本篇文章,让我们一起学习一下如何在linux系统下完成进度条的打印。

二、了解回车符、换行符和刷新缓冲区

:表示回车,回到当前行的行首,而不会换到下一行,如果接着输出的话,本行以前的内容会被逐一覆盖(光标在该行的头部) 或 :表示换行,换到当前位置的下一行(光标在下一行的头部)
#include <stdio.h>
  2 
  3 int main(){
          
   
  4 
  5     printf("hello world
");                                                                                                                                                         
  6     return 0;
  7 
  8 }
[wmh@VM-24-5-centos ]$ vim test.c
[wmh@VM-24-5-centos ]$ gcc test.c
[wmh@VM-24-5-centos ]$ ./a.out
hello world
[wmh@VM-24-5-centos ]$

上述代码我们使用vim创建了一个.c文件,当在打印行末尾输入“ ”或“ ”的时候,光标会先到hello world行首,再往下换行,显示出以上界面

[wmh@VM-24-5-centos ]$ gcc test.c
[wmh@VM-24-5-centos ]$ ./a.out

当我们修改代码,去掉“ ”的时候,我们再次编译运行可以发现,没有打印结果,当打印到“ ”的时候,光标会回到行首,并覆盖之前的内容,导致没有打印结果,但是hello world仍在缓冲区,并没有被删除,只是没在页面上显示出来。

缓冲区有自己的刷新策略(这里是行缓冲),当遇见有“ ”的时候,缓冲区会把 及其之前的所有内容刷新出来。这是之前能打印出来的原因。

通过上述代码以及文字解释,相信大家也有了简单的认识,当只存在“ ”的时候,打印数据会被覆盖,而没有打印到屏幕,既然缓冲区里还有,那我们可以通过手动刷新缓冲区,取出他的打印结果。

1 #include <stdio.h>
  2 #include <unistd.h>                                                                                                                                                                    
  3 int main(){
          
                               
  4                                        
  5     printf("hello world
");           
  6     fflush(stdout); //刷新缓冲区,stdout姑且认为是屏幕                   
  7     sleep(1); //间隔时间1s 
  8  	printf("
);                      
  9     return 0;                                                                                                               
  10                                                                                                                             
 11 }
[wmh@VM-24-5-centos ]$ gcc test.c
[wmh@VM-24-5-centos ]$ ./a.out
hello world
[wmh@VM-24-5-centos ]$

再次运行可以看到显示结果打印到了屏幕上。

三、打印进度条

铺垫了这么久,接下来我们看一下进度条的实现 核心思想也是利用“ ”和缓冲区,实现不断的覆盖打印

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

//进度条大小
#define SIZE 102
//进度条样式
#define STYLE =
//进度条指示器
#define S >

void show(){
          
   
  const char* tmp="|/-\";//是否处于加载中
  char arr[SIZE];
  memset(arr,0,sizeof(arr));
  int i=0;
  while(i<=100){
          
   
  	
  	//printf("[%-100s]][%d%%][%c]
",arr,i,tmp[i%4]);简单版
  	//设置进度条样式,添加背景色,字体颜色等
     printf("[33[43;31;1m%-100s33[0m]][%d%%][%c]
",arr,i,tmp[i%4]);
      fflush(stdout);                                                              
      arr[i++]=STYLE;
      if(i != 100) arr[i]=S;
      usleep(100000);//100000微秒
  }
printf("
");
}

演示效果: 运行上述代码应是一个动态的进度条,这里我只截了一张图

经验分享 程序员 微信小程序 职场和发展