【Linux】进度条小程序
创始人
2024-05-15 04:36:17
0

目录

  • 一.\r && \n
  • 二.行缓存区概念
    • 问题:
    • 解答:
    • 检测:
  • 三.进度条
    • 1.进度动态条
    • 2.进度百分比
    • 3.小装饰
    • 4.颜色

该篇博客会主要按步骤推导出一个在Linux上运行的进度条小程序,会用到vim编辑器和gcc编译器,如果对这两个软件不熟悉,可以点击链接,结合该篇博客学习,进度条小程序展示如下:
在这里插入图片描述

一.\r && \n

c语言有很多的字符,但宏观上可以分为两种:可显字符控制字符

可显字符:A、a、B、c…等字符

控制字符:\n(回车)、\t(水平制表)、\r(换行)等

这里我们需要在Linux系统下使用\r\n两字符

一般,我们在C语言中使用\n进行换行,或在使用电脑的Enter键进行换行,是直接将其换到下一行的最左侧处

int main()
{printf("Hello\nWorld!");return 0;
}

在这里插入图片描述

但事实上,这是两个动作,只是在语言的范畴,C语言使用\n完成了换到下一行回到当前最左侧这两个动作。

像我们之前的老式键盘,回车键与现在的回车键不同,表示该键位是两个动作的和。

在这里插入图片描述
所以我们平时所指的换行都是由这两个动作组成的。

了解了上面的知识,我们在来看一下\r\n的意义

\r:回车(回到当前行最左侧)

\n:换行(换到下一行)

在这里插入图片描述
在我们使用C语言进行\n换行,在语言层面,默认进行了换行+回车两个动作

二.行缓存区概念

问题:

我们首先观察下面两个段代码的在Linux下运行后的区别

  • 会将两段代码的可执行文件都命名位MyTest,并运行展示

  • 代码中会用到sleep函数,可以使用man指令,在3号手册中查找(Linux常见指令)

    man 3 sleep
    

    在这里插入图片描述

    • 作用:在当前代码处暂停,单位秒。

代码1

#include
#includeint main()
{printf("hello world\n");//使用换行符'\n'sleep(3);//暂停3秒后继续运行return 0;
}

在这里插入图片描述
代码2

#include
#includeint main()
{printf("hello world\r");//使用回车符'\r'sleep(3);//暂停3秒后继续运行return 0;
}

在这里插入图片描述

按照我们正常的逻辑,两段代码都应该打印出东西,但是代码2只执行了sleep,什么都没有打印出来,这是为什么?是不是和\r\n有关系呢?

这个问题就涉及到了缓存区的概念(我们这里简单的了解一下,缓冲区剩余的内容会在之后的博客中)

解答:

我们在来看一下,下面这段代码及其运行结果:

代码3

#include
#includeint main()
{printf("hello world");sleep(3);//暂停3秒后继续运行return 0;
}

在这里插入图片描述

我们可以看到上面的结果,好像这次是先执行了sleep函数,在执行了printf,又在输出的字符串后,输出了命令行。

  • C语言的代码执行的是顺序结构,必须按顺序和代码逻辑依次执行,所以一定是printf先执行,然后是sleep。

  • printf即被执行,需要有一个地方临时存放字符串,这个地方就是缓存区

  • 当代码被执行完,缓存区被刷新,字符串被打印到屏幕上,此时光标(绿色光标)的位置在字符串的后面。

  • 在Linux中,每次像显示器打印数据都是从光标的位置开始,即:光标和显示器匹配,光标在哪里,就在哪里开始打印。

  • 所以命令行会直接打印在字符串后面。(代码1进行了换行,光标在新的一行)

  • 不同的平台缓冲区的表现形式不同,在Linux中,缓存区有自己的刷新策略(很多)

    我们现在看的是行缓存,它会在六种情况下刷新缓存区(只介绍三条,其余内容与该文无关)

    1. 遇到换行符,如:\n。(代码1先看到字符串后sleep的原因)
    2. 程序结束的时候。(代码三的情况)
    3. 主动刷新

从上面的内容,我们就能分析除代码2执行不成功的原因:

printf函数执行后,并没有使缓冲区刷新,数据保存在缓冲区内,执行sleep后,字符串在显示器上打印,但在之前的内容中我们指定\r为回车,将光标返回到这一行的最左边,然后命令行在光标开始处打印,将字符串内容覆盖。我们什么都看不到了。

那有办法解决这个问题吗?答:我想不出来,只要我们还将\r放在字符串最后面,字符串终会被命令行覆盖,即使我们使用其他控制字符,显示出结果,但结果终究和我们想要的不同。

这里我们倒是可以利用上面介绍的刷新缓存的第三种方法,来检测我们的解答是否正确,看到字符串在屏幕上出现并消失。

检测:

我们要主动刷新缓冲区,需要使用fflush函数,我们同样可以用man指令在3号手册中查找。Linux常见指令

man 3 fflush

在这里插入图片描述

测试代码如下:

#include
#includeint main()
{printf("hello world\r");//使用回车符'\r'fflush(stdout);//自动刷新缓存区sleep(3);//暂停3秒后继续运行return 0;
}

在这里插入图片描述

我们从结果看出,事实就是如此,它的光标移到了最左边,命令行打印时将其覆盖,我们在代码2中看不到结果。

拓展

凡是向显示器打印的所有的内容,都是字符

printf("%d",123);
//打印的123,分别为'1'、'2'、'3'

三.进度条

展示效果:

在这里插入图片描述
我们可以利用上面缓存区的知识,使用C语言在Linux上实现这样的一个小程序

一个这样的小程序我们可以简单将其分为如下图的四个部分:

在这里插入图片描述

1.进度动态条

进度条的增长的图形我设置为 = ,并以 > 符号开头

进度条的设置是从0%到100%(0%无进度),我们需要大小100个=,还需要1个 > ,在最后加一个终止符\0,共102个字节存储,也就是存储进度条的char类型的数组大小为102。

注意:创建了数组后,需要对其继续初始化,使其102个字节都为\0,方便每次到达更新的位置后准确停下。

我们要它每加载百分之一就刷新一次,需要将打印的数组放在循环内,将\r放在要打印的字符串后面,在使用fflush(stdout)来自动刷新缓存区,在使用usleep(sleep单位秒,usleep单位微妙,可以自己尝试一下看看用那个更合适)将每次循环暂停一下在继续,这样就能展示出进度条上涨的形状。

在这里插入图片描述
在这里插入图片描述

2.进度百分比

我们在循环中打印进度条,只要打印时在将循环的次数打印即可,注意:百分号表示为%%,不能使用\%,会报警,有先平台上编译会显示失败。

修改上述代码如下

printf("[%-100s][%d%%]\r",bar,i);

3.小装饰

在进度条的最后,我们增加了一个旋转的光标,使其看着更加生动,

这里使用| / - \四个符号来表示光标,将其存入数组,注意:\表示转移字符,要使用两个\来表示一个

顺时针旋转:“|/-\”

逆时针旋转:“|\-/”

这里使用顺时针,完整的修改代码如下:

  #include    #include    #include    #define N 101    #define STYLE '='    int main()    {    char bar[N];    memset(bar,'\0',sizeof(bar));    char lable[4] = "|/-\\";    int i=0;    while(i<=100)    {    printf("[%-100s][%d%%][%c]\r",bar,i,lable[i%4]);                                                                                      fflush(stdout);    usleep(100000);    bar[i++] = STYLE;    if(i!=100) bar[i] = '>';    }    printf("\n");    return 0;    }   

在这里插入图片描述

4.颜色

想要使我们输出的进度条改变颜色有很多种方法,这里我只展示一种,有兴趣的可以自己去搜索

//格式
printf("\e[31m字符串\e[0m");//31:前景色
//\e[31 :开头
//\e[0m :终止,使改变的颜色只在字符串内

前景色(字体颜色)

字符颜色
30黑色
31红色
32绿色
33黄色
34蓝色
35紫色
36深绿
37白色

有了这些知识,我们就能改变进度条的颜色,将其变为红色,代码如下:

#include
#include
#include#define N 101
#define STYLE '='int main()
{char bar[N];memset(bar,'\0',sizeof(bar));const char* lable = "|/-\\";int i=0;while(i<=100){printf("[\e[31m%-100s\e[0m][%d%%][%c]\r",bar,i,lable[i%4]);                                                               fflush(stdout);                                                   usleep(100000);                                                   bar[i++] = STYLE;if(i!=100) bar[i] = '>';}                         printf("\n");             return 0;    
}  

在这里插入图片描述
关于进度条颜色和形状不仅仅只有这些,大家感兴趣可以去搜索更多的内容,自己创建一个特别的进度条。

相关内容

热门资讯

永远会用安卓系统的手机 亲爱的手机控们,你是否也有那么一款手机,它陪伴你度过了无数个日夜,成为了你生活中不可或缺的一部分?没...
安卓系统怎么添加公众号,安卓系... 你是不是也和我一样,对安卓手机上的公众号情有独钟呢?想要把那些有趣的公众号添加到手机里,随时随地都能...
仿苹果系统怎么改回安卓系统,轻... 你是不是也和我一样,曾经被苹果系统的魅力所吸引,然后不小心把手机换成了安卓呢?现在,突然发现安卓的某...
oppor11plus安卓系统... 你有没有注意到,最近手机圈里又掀起了一股热潮?没错,就是OPPO R11 Plus这款手机。这款手机...
安卓系统重新洗牌教程,从重新洗... 你有没有发现,安卓系统最近好像经历了一场大洗牌?别急,别急,让我来给你详细介绍一下这个安卓系统重新洗...
安卓12系统改画质,尽享极致流... 你有没有发现,最近你的安卓手机好像变得不一样了?没错,就是那个神秘的安卓12系统,它悄悄地给你带来了...
小米11系统是安卓几,探索新一... 你有没有发现,最近小米11这款手机在市场上可是火得一塌糊涂呢!那么,问题来了,小米11的系统是安卓几...
安卓版系统下载安装 你有没有想过,为什么你的手机总是那么卡,那么慢?别急,今天就来给你揭秘,如何让你的安卓手机焕然一新,...
安卓换苹果系统更新多久,体验无... 你有没有想过,当你把心爱的安卓手机换成苹果,那系统更新到底要等多久呢?这可是不少人在换机时都会关心的...
如何升级华为的安卓系统,轻松提... 亲爱的手机控们,你是不是也和我一样,对华为的安卓系统充满了好奇和期待?想要让你的华为手机焕然一新,体...
好用系统插件推荐安卓手机,提升... 你有没有发现,手机用久了,是不是觉得有点力不从心?别急,今天就来给你安利一波好用系统插件,让你的安卓...
x3鸿蒙系统和安卓系统,探索x... 你知道吗?最近手机圈里可是热闹非凡呢!各大品牌纷纷推出新机,而其中最引人注目的莫过于华为的新操作系统...
安卓系统优化手机软件,打造流畅... 你有没有发现,你的安卓手机最近变得有点“慢吞吞”的?别急,别急,今天就来给你支几招,让你的安卓手机焕...
安卓车机系统显示歌词,打造沉浸... 亲爱的车友们,你是否在驾驶过程中,被那美妙的旋律和歌词所吸引,却又因为无法专注于路面而感到困扰?别担...
安卓系统硬件是否损坏 手机突然卡顿,屏幕闪烁不定,是不是安卓系统的硬件出了问题?别急,今天就来给你详细剖析一下安卓系统硬件...
3310安卓4g系统,智能升级 你有没有听说过3310安卓4G系统?这可是最近科技圈里的小热门呢!想象一个经典的诺基亚3310,竟然...
小米用的安卓系统吗,引领智能生... 你有没有想过,那个你每天不离手的手机,它的操作系统到底是谁家的“孩子”?今天,咱们就来聊聊这个话题—...
安卓系统厉害的游戏,盘点那些令... 你有没有发现,安卓系统上的游戏真的是越来越厉害了?没错,我就要给你好好盘点一下那些让人欲罢不能的安卓...
安卓手机系统提有声音,唤醒你的... 你有没有发现,最近你的安卓手机系统突然变得特别贴心呢?没错,就是那个一直默默陪伴你的小家伙,现在竟然...
安卓9系统设置密码破解,轻松应... 你有没有遇到过这种情况:手机里装了安卓9系统,不小心设置了密码,结果现在想找回数据,却因为密码而头疼...