今天为大家带来一篇关于在Linux上编写的进度条小程序的博客。
正文
我们在日常生活中使用电子产品时,经常会遇到加载的过程,这时候这些加载界面总是会附带有一些进度条,这些进度条是加载进度的可视化图形,这篇文章我们就在Linux系统下编写一个进度条,主要关注进度条程序的原理和模拟应用。
缓冲区
在写进度条之前,我们先来了解一下关于C语言中的缓冲区的知识。
首先我们看看下面这段代码的结果:
#include <stdio.h>
#include <unistd.h>int main()
{printf("Hello world!");while(1) sleep(1);return 0;
}
结果如下:
我们可以发现,上面的代码并没有输出Hello world! 而是一直在睡眠,我们知道,C语言在主函数中是按照从上往下的顺序来执行语句的,那么这里为什么没有先输出而是一直在睡眠呢?
这是C语言中的缓冲区在起作用,缓冲区可以提高CPU的效率,它是内存空间中预留的存储空间,这些存储空间用来缓冲输入或输出的数据。
其中,缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。
我们的Hello world就是被存储在输出缓冲区中,由于我们使用的输出函数 printf() 对应的缓冲类型为行缓冲,在这种情况下,填满缓冲区、有换行符'\n'或者调用fflush函数强制刷新缓冲区会立即输出。(除此之外,程序结束时也会进行刷新缓冲区)而我们写在上面的输出语句没有达成刷新缓冲区的条件,于是就产生了以上的结果。
所以我们可以使用fflush函数强制刷新缓冲区,或者在输出的字符串之后加上'\n'来保证这种情况下的正常输出。
进度条
我们现在正式开始编写一个进度条小程序,首先,我们先关注进度条的特点:代表进度的符号都聚集于一行并且其数量一般从左向右不断增加,而且常常会标注进度的百分比表示。
那么我们首先实现进度条的主体部分,也就是在某一行中不断向右增长的条状物。要实现这个部分,我们需要使用到上面关于缓冲区的知识:由于进度条始终在同一行中展示(也就是字符串中没有换行),我们的每次输出都必须要刷新缓冲区。除此之外,我们进度条的每一次输出都需要使光标回车到最左侧位置,这点需要我们注意使用转义字符'\r',下面我们展示代码:
processbar.c:
#include "processbar.h" const char* lable = "|/-\\";
char bar[NUM];
// 这段代码显示了进度条的原理
void processbar(int speed)
{char bar[NUM];memset(bar, '\0', NUM);int len = strlen(lable);int i = 0;while(i <= TOP){printf("[%-100s][%d%%][%c]\r", bar, i, lable[i%len]);fflush(stdout);bar[i++] = BODY;if(i < 100) bar[i] = RIGHT;usleep(speed);}printf("\n");
}
这是进度条的主要函数的代码,通过上面的函数,我们可以在调用时传入进度条持续增长的速度,除了进度条的主体之外,我还在旁边添加了对应进度的百分比数字和顺时针旋转的一根杠作为修饰。最后我们输出换行防止下一命令行将我们的进度条覆盖。
processbar.h:
#pragma once #include <stdio.h>
#include <unistd.h>
#include <string.h> #define NUM 102
#define TOP 100
#define BODY '='
#define RIGHT '>' extern void processbar(int);
main.c:
#include "processbar.h" int main()
{processbar(50000);return 0;
}
当我们得到了上述的三个文件,我们便可以编译运行在屏幕上输出想要的结果,这时我们可以使用上一篇文章中介绍的项目自动化工具——make和makefile来完成编译和清理的工作。
makefile:
processBar:processbar.c main.c@gcc -o $@ $^
.PHONY:clean
clean: @rm -f processBar
于是我们使用make指令得到可执行文件:
[butterfly@VM-24-9-centos processbar]$ make
[butterfly@VM-24-9-centos processbar]$ ls
install.sh main.c Makefile processbar processbar.c processbar.h
然后我们执行得到的可执行文件:
这样我们便运用学到的知识实现了进度条的基本原理,谢谢大家!