大家好,我是苏貝,本篇博客带大家了解Linux的编译器-gcc/g++,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在我们使用手机/电脑时,经常会出现要下载或更新软件的情况,此时就会出现进度条
让我们来了解一下如何用Linux实现一个简易的进度条
1. \r&&\n
我们在C语言中就经常使用\n,\n=回车+换行。
回车和换行是什么意思呢?
回车:回到本行的最前面
换行:到本行位置的下面一行
我们键盘中的entry键就是回车+换行
那有没有只回车的符号呢?有的,\r
2. 缓冲区
我们先了解一下sleep函数
语言中的 sleep 函数可以让当前线程暂停执行一段时间,通常用于模拟实际运行环境下的等待或延时操作。在 Windows 和 Linux 等主流操作系统中,sleep 函数的实现方式略有不同,但其基本原理都是通过让线程进入睡眠状态来实现等待或延时的效果。
在VC中,Sleep中的第一个英文字符为大写的"S" ,在linux下是sleep, 不要大写,简单的说VC用Sleep, 别的一律使用sleep
在VC中,Sleep()是以毫秒为单位,所以如果想让函数滞留1秒的话,应该是Sleep(1000); 在Linux下,sleep()以秒为单位,而非毫秒。
我们写出有下面内容的文件
1
编译运行该文件后,我们发现,屏幕上先打印出了hello world!,然后间隔3秒才退出程序
再修改该文件,如下图,与之前内容相比,只是去掉了\n
2
编译运行该文件后,我们发现,先间隔3秒,屏幕上才打印出了hello world!,然后退出程序
我们知道,C语言中有3大结构:顺序、选择、循环。该文件遵循顺序结构,所以printf函数一定先于sleep函数执行,可是结果却不是先打印在屏幕上再睡眠,那在sleep期间,字符串在哪里呢?
字符串在缓冲区。
什么时候会冲刷缓冲区(将缓冲区的内容显示到屏幕)?
1.程序结束的时候,会自动冲刷缓冲区
2.缓冲区满了
3.有\n
4.强制刷新缓冲区fflush(stdout)
所以上面程序运行时,先将字符串放在缓冲区,因为没有\n、强制刷新、缓冲区没有满,所以字符串还是呆在缓冲区,再执行sleep函数,最后程序结束,自动冲刷缓冲区,所以字符串显示在屏幕上
3
现在给该文件加上强制刷新,编译运行发现,先在屏幕上打印出字符串,间隔3秒后再退出程序
3. 简单的倒计时
我们来写一个从10开始的倒计时,一定要用\r,因为10存放在缓冲区中,所以要强制刷新缓冲区使之打印在屏幕上
#include<stdio.h> #include<unistd.h>
int main()
{
int i=10;
while(i>=0)
{
printf("%-2d\r",i);
fflush(stdout);
sleep(1);
i--;
}
return 0;
}
4
这样写的代码有缺点,即最后倒数的0会被覆盖,因此我们再在程序结束前\n,这样就可以避免该问题
#include<stdio.h> #include<unistd.h>
int main()
{
int i=10;
while(i>=0)
{
printf("%-2d\r",i);
fflush(stdout);
sleep(1);
i--;
}
printf("\n");
return 0;
}
5
4. 进度条
经过上面的了解后,我们终于可以开始进度条的学习
想实现 [ ] [ % ] [ |/-\ ]
其中第一个 [ ] 内,显示#,最多有100个#,一个#表示1%,当已经进行到20%时,[ ] 内就有20个#。第二个[ ] 显示进行到了百分之多少。第三个[ ] 显示旋转进度条,今天我们只弄简单的旋转进度条|/-
7
初级进度条:
我们创建3个文件ProcessBar.h 、ProcessBar.c 和Main.c
先写makefile文件
mytest:ProcessBar.c Main.c
gcc -o $@ $^
.PHONY:clean
clean:
rm -f mytest
Mytest是目标文件(默认为a.out,-o就是修改生成的可执行程序的文件名),ProcessBar.c和Main.c是依赖文件列表,列表里可以没有ProcessBar.h,因为在生成mytest时要执行gcc -o $@ $^即gcc -o mytest ProcessBar.c Main.c命令,gcc在预处理时就会头文件展开,所以不需要ProcessBar.h
再写ProcessBar.h
我们的进度条函数名为ProcBar,不需要传参
再写ProcessBar.c
我们先实现第一个[ ] ,要在5秒内显示所有的#,所以1%只睡眠1/20秒。因为sleep函数的参数的单位是秒,类型为unsigned int,所以我们采用usleep函数,单位是微秒
接下来实现其它两个[ ] 的内容
最后写Main.c
7
进阶进度条
在实际生活中,与进度条有关的是带宽(单位时间内传输的数据量)和文件总大小。所以我们要先获取带宽,但这需要网络方面的知识,所以带宽暂时就直接定义。
Makefile文件不变
先写Main.c
带宽:1MB
文件大小:100MB
再写ProcessBar.c
再写ProcessBar.h
8
好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️