【Linux】第一个小程序—进度条

发布于:2025-07-18 ⋅ 阅读:(14) ⋅ 点赞:(0)

1.回车换行概念

抽象以写作文为例,当在一行中写了一半,由此处位置往下一行的操作叫做换行,回到该行的开头位置为回车,回车和换行是两个不同的概念。在计算机中的操作也是如此

C语言中\n代表换行,但实际回车换行两个操作都做了 ,默认的编译器和语言帮我们做解释了,\r代表回车

2.缓冲区概念

1.执行该代码现象是先打印出来然后休息2s,sleep函数是Linux中的一个系统调用,调用时会让系统休息设定的时间,可通过指令man 3 sleep来查看手册在这里插入图片描述

2.去掉回车换行符之后现象是先休息再打印,由于没有\nshell命令行跟在打印结果后运行
在这里插入图片描述
在这里插入图片描述
若没有循环调用函数等条件,C语言一定是从上往下按顺序执行。这就说明在sleep期间,输出内容一定是被保存起来了,被保存到缓冲区中(一段由C语言维护的内存)

3.C程序会默认帮我们打开三个输入输出流文件,标准输入、标准输出(显示屏,stdout)、标准错误,若想要强制刷新可以使用fflush
在这里插入图片描述
打印消息是往stdout中打的,暂存在stdout文件流当中,默认当程序结束时刷新
在这里插入图片描述

简单倒计时

1.该代码执行后不会立马刷新,因为没有+\n,数据都存在缓存区中。但是如果加了\n会换行,我们希望倒计时在一行内完成
在这里插入图片描述
2.加入fflush后可以立马刷新,但是数据是依次打印,倒计时应该是覆盖数据
在这里插入图片描述
3.此时我们应该输出数据后跟\r仅表示回车,将输入光标移动到开头
在这里插入图片描述
此处有个细节,当从键盘输入数据时输入的是一个个字符,并不是一个整数,所以当字符位长不一样时,没输入的位会显示0。比如倒计时10、90、80等等,可以用设置位宽来解决即%2d,没有输入字符的位显示空,此时倒计时会显示10、09、08等等;若使用%-2d就是采取左对齐的方式输出即10、9、8等等

3.实现进度条

细节控制:

1.usleep和sleep一样功能是休眠,但是时间单位为微秒,1s=1×10^3ms =1×10 ^6 μs,加入想让程序10s打印100个数每个数打印0.1s,需要10万微秒即可
在这里插入图片描述
2.C语言在进行输出显示时如果预留空间了默认是右对齐,打印时就会从右向左
3.想在打印字符时显示打印的个数情况,C语言中想显示%,就在格式化控制输出后+%%,一个%是控制格式化输出的特殊字符,想显示就要两个,或者是转义字符+%
4.想在打印时模拟加载的情况需要用一个字符数组来依次覆盖输出|/-\四个字符,与倒计时的方法类似,有两个\是因为其中一个为转义字符

3.1processbar.h头文件

在这里插入图片描述
1.用两个宏来进行替换,NUM是数组大小包含了C语言字符串结束条件\0,STYLE用来表示进度条的输出风格,我们可以更换其中字符
2.进行函数声明,extern表示告诉编译器存在这个函数声明,但实现在其他的文件,等到编译链接阶段,再去找到它的真正实现,保证调用不出错。函数是默认外部可链接的,所以更适用于变量的声明

3.2processbar.c源文件

在这里插入图片描述

1.const char* lable:

定义一个字符数组,内容是 |/-|,用于进度条末尾显示动态旋转的 “小图标”(通过 cnt%3 循环切换)。

2.char bar[NUM]:

NUM 是在 processbar.h 里定义的常量,用来存进度条的字符(比如 # 或其他符号)。memset把 bar 数组全部初始化为 \0(字符串结束符),相当于清空,为后续填充做准备。

3.\r 是 “回车符”

会让光标回到行首(但不换行)。配合 %-100s,能让进度条在同一行反复刷新,模拟动态效果

4.格式 [-%100s] [%d%%] [%c]:

-%100s:左对齐占 100 个字符宽度,用 bar 内容填充(随 cnt 增加,bar 里的有效字符变多,视觉上就是进度条 “变长”)。
%d%%:显示百分比数字(cnt 从 0 到 100)。
%c:从 lable 里取字符(cnt%3 让 |/-| 循环切换,像小图标在转)。

5.fflush(stdout):

默认情况下,printf 输出会缓冲(不会立即显示到屏幕)。fflush(stdout) 强制把缓冲区内容刷到屏幕,保证进度条实时刷新。

6.整体效果

运行后,你会在命令行看到:
一个动态增长的进度条(用 STYLE 字符填充,最多 100 个字符宽度)。
右侧显示百分比数字(0% ~ 100%)。
最右侧有一个旋转的小图标(|/-| 循环切换)。

3.3main.c源文件

在这里插入图片描述

3.4makefile自动化构建

在这里插入图片描述
$@ → 目标文件名(要生成的结果)
$^ → 所有依赖的源文件(用来生成目标的原材料)
.PHONY → 声明伪目标,避免和同名文件冲突,即每次都执行该操作
命令前的 @ → 隐藏命令执行时的回显

4.进度条的调用场景模拟

4.1processbar.h头文件

在这里插入图片描述
主要用于声明常量和函数,方便其他源文件进行调用,起到接口定义的作用
1.#define常量定义
让代码更可读和维护,只需要在此处修改依次即可
NUM:进度条数组长度(比如进度条最多显示 102 个字符)。
BODY:进度条主体字符(比如用 = 填充进度条)。
TOP:进度条的上限(比如 100% 对应的值)。
RIGHT:进度条末尾的符号(比如用 > 表示进度条尖端)
2.函数声明:extern:
目的告诉编译器函数的实现在其他源文件中,先声明,允许调用

4.2processbar.c源文件

在这里插入图片描述
1.全局变量与动画字符
lable:实现进度条的动态旋转效果(比如下载时常见的 |/-\ 循环动画)。
bar:存储进度条的字符内容(比如用 = 填充,末尾用 > 标识,来自头文件的 BODY 和 RIGHT)。
2.processbar 函数:绘制进度条
接收一个 rate(0~100),表示进度百分比。用 printf 结合 \r 加上fflush实现单行动态刷新,让进度条在同一行更新,模拟 “进度推进” 效果。用 bar 数组逐步填充 BODY(如 =),构建进度条的视觉效果。
3.initbar 函数:初始化进度条
每次开始新的进度条前,调用 initbar 清空 bar 数组,避免残留旧数据影响显示。

4.3main.c源文件

在这里插入图片描述
1.函数指针类型定义:
给函数指针起别名 callback_t,方便后续用它声明变量(比如 download 的参数 cb)。
2.核心逻辑
download 只负责模拟下载过程,不关心进度怎么显示。具体的进度显示
由调用 download 时传入的回调函数决定。
在这里插入图片描述
模拟多过程下载

makefile自动化构建与上文相同


网站公告

今日签到

点亮在社区的每一天
去签到