本文主要讲解在
linux
系统下实现进度条以及倒计时小程序
看似花哨,其实很容易的,我们只需要了解两个知识点即可
1. \r和\n
2. 行缓冲区
3. 关于make
和makefile
,大家看我前面几篇博客,因为小项目里面也使用了这个知识点
大家跟我一起学起来吧!
\r和\n
我们再学C语言的时候,我们有很多字符,一种是可显字符,另一种是控制字符
我们在一行内容没有写完,然后要换到下一行的开始,我们要进行两个操作,
1:\n(换行)
让光标从第一行跳到第二行,但是光标只是垂直向下跳,并没有在第二行的开始。
2:\r(回车)
在第二行让光标跳到最开始的位置,这个操作就是回车。
有的同学就问,我们在C语言的时候,怎么用\n来换行加回车。这是我们在这个语言环境下我们将其简化,此时的\n就表示回车加换行。
我们一共测试四种情况,
(1):\r和\n
都存在
(2):\r和\n
都不存在
(3):只有\n
,
(4):只有\r
。
\r和\n
都存在现象:就相当于\n
,直接跳到下一行的开头
\r和\n
都不存在现象:
linux
命令行紧跟着打印的信息,
因为我们结尾啥都没有,那光标就还在结尾,所以linux
命令行紧跟我们的打印信息
只有\n
这个就是和我们的换行+回车,和我们平时用的一样,只不过我们的编译器将两步简化为一步了,我们只需要输入\n即可
只有\r
现象:看不到打印的信息了。只能看到linux命令行
解释:因为我们\r
,只有回车的效果,我们本来光标在文本行的最后一个字符旁边,但是我们识别到\r字符,所以,直接回车,光标来到了文本行的开始。这时linux
的命令行就会从光标处开始,将我们的文本覆盖掉,我们就什们都看不到。
#include
#include
int main()
{
printf("hello world");
sleep(3);
}
现象:我们发现,
hello world
没有立刻刷新出来,数据一定在sleep
期间被保存起来,但是我们加上\n
,数据就会先显示出来。
就是因为缓冲区有自己的行缓冲刷新策略。
我们知道了上面两个知识点,\r将光标回到最开始就可以将其覆盖掉,所以我们利用这个特点可以写一个倒计时小程序,我们先写一个10秒以内的倒计时小程序。
1 #include<stdio.h>
2 #include<unistd.h>
3
4 int main()
5 {
6 int i=0;
7 for(i=9;i>=0;i--)
8 {
9 printf("%d\r",i);
10
11 sleep(1);
12 }
13 return 0;
14 }
我们发现这样倒计时不显示,原因是数据存放在缓冲区里,我们没有刷新缓冲区,所以我们没有显示,所以我们修改一下就OK了
1 #include<stdio.h>
2 #include<unistd.h>
3
4 int main()
5 {
6 int i=0;
7 for(i=9;i>=0;i--)
8 {
9 printf("%d\r",i);
10 fflush(stdout); //刷新缓存区
11 sleep(1);
12 }
13 return 0;
15 }
这样我们的倒计时代码就改好了,但是如果我们突然变成10秒以后的,发现不能将两位数字都覆盖掉,因为最后由两位数变成了1位数,所以我们还要做一点修改。
1 #include<stdio.h>
2 #include<unistd.h>
3
4 int main()
5 {
6 int i=0;
7 for(i=9;i>=0;i--)
8 {
9 printf("%-2d\r",i);
10 fflush(stdout);
11 sleep(1);
12 }
13 return 0;
15 }
~
进度条样式 :
=>
推进的方式呈现,比如:[======]
[= ]
[num%]
显示,num
随着进度条的不断推进而变化 [\]
的样式,顺时针不断旋转[========>] [15%] [\]
采用多文件 :
文件存放在 proc 目录中
proc.h
1 #pragma once
2 #include <stdio.h>
3 #include <unistd.h>
4 #include <string.h>
5
6
7 //进度条函数
8 void Progress();
proc.c
#include "proc.h"
2
3 void Progress()
4 {
5 const char* label = "|/-\\";//多加一个\是防止\成为转移字符
6 char bar[101];
7 memset(bar,'\0',sizeof(bar));//将数组全部初始化为\0,因为如果不初始化的话,数组的元素是随机值
8
9 int i = 0;
10 while(i <= 100)
11 {
12 printf("[%-100s][%d%%] [%c]\r",bar,i,label[i%4]);
13 fflush(stdout);//刷新缓冲区
14
15 bar[i++] = '#';//每次向数组写一个#
16 usleep(100000);
17 }
18 printf("\n");
19 }
main.c
#include "proc.h"
2
3
4 int main()
5 {
6 Progress();
7 return 0;
8 }