🪅1. 回车换行
在学习C语言的时候,我们输出的时候,通常会使用\n
,进行换行输出。其实这的所谓的换行,包含了2个操作:回车、换行。
♥1.1 回车
回车的本意是将光标回车到当前行的最前面,在C语言中\r
表示回车。
#include<Windows.h>
int main()
{
int cnt = 15;
while (cnt--)
{
printf("%-2d\r", cnt);//回车
Sleep(100);
}
return 0;
}
这就是回车的现象,这里按理说最后应该会输出到0停止,然后将0显式到终端。
程序结束之后会自动回车换行,所以这里的回车换行就覆盖了0。
♥1.2 换行
换行的意思就是换一行,将光标换到当前行的下一行,C语言中将换行符\n
其实是合并成了回车换行。
#include<Windows.h>
int main()
{
int cnt = 15;
while (cnt--)
{
printf("%-2d\n", cnt);//回车换行
Sleep(100);
}
return 0;
}
🪆2. 缓冲区现象
#include<stdio.h>
#include<unistd.h> //sleep所需头文件
int main()
{
printf("hello linux"); //1
sleep(1); //休眠一秒钟 //2
return 0;
}
在Linux中,执行这段代码,我们观察到并不是直接输出hello linux
,而是先休眠2秒,在输出hello linux
。
这并不是因为先执行了sleep(1)
,而是hello linux
被保存在了缓冲区,,这个缓冲区是有C语言提供的。
由于没有\n
换行刷新,所以当这段程序结束时,缓冲区的数据才会被刷出。如果想要将这段数据强制刷新出来,需要了解三个东西:
- 标准输入
- 标准输出
- 标准错误
C程序默认会打开三个输入输出流,在Linux下,一切皆文件,显示器也属于文件,显示器所对应的文件类型是stdout
。
fflush
函数是标准C库中的一个函数,用于刷新流的输出缓冲区。我们可以调用这个函数强制刷新缓冲区。
🧸3. 进度条实现
♟3.1 逻辑
- 确定进度条的总长度和当前角度的比例
- 根据比例计算出当前进度条的填充长度
- 使用特定的字符表示填充部分
- 进度条旁边显示百分比完成的信息
进度条的实现,我们也是分三个文件:
- 头文件:
proceeBar.h
- 逻辑实现:
processBar.c
- 测试文件:
main.c
♟3.2 进度条样式
♟3.3 代码实现
processBar.h
#pragma once
#include<stdio.h>
#include<unistd.h>
#include<string.h>
//0~100 有101个字符,\0也需要一个空间 -->102
#define NUM 102
//填充部分的字符(根据自己喜欢选择)
#define STYLE '-'
//循环次数
#define TOP 100
//右侧字符
#define RIGHT '>'
//进度条函数声明
extern void processbar(int rate,int cur);
//初始化
extern void initbar();
processBar.c
#include"processBar.h"
const char* lable = "|/-\\";
char bar[NUM];
void initbar()
{
memset(bar,'\0',sizeof(bar));
}
void processbar(int rate,int cur)
{
int len = strlen(lable);
//进度为0~100
if(rate < 0 || rate > 100) return;
//进度为多少就设置多少个 如果一个一个增加,那么就会出现->->这种现象 因为进度可能每次加的都不是1
memset(bar, STYLE, rate);
if(rate<100)
{
//右侧箭头
bar[rate++] = RIGHT;
printf("[%-100s][%d%%][%c][已下载:%dMB]\r", bar,rate,lable[rate%len],cur);
}
else
{
printf("[%-100s][%d%%][%c][已下载:%dMB]\r", bar,rate,lable[rate%len],cur);
//bar为全局函数,每次调用完之后初始化
initbar();
}
fflush(stdout);
}
🃏4. 场景使用
进度条一般在下载场景中使用,我们可以用main.c
来进行模拟下载
#include"processBar.h"
//回调函数
typedef void (*callBack_t)(int,int);
//模拟下载
void downLoad(callBack_t cb)
{
//下载目标
int total = 0;
printf("要下载多少MB:");
scanf("%d",&total);
//当前进度
int cur = 0;
printf("当前进度多少:");
scanf("%d",&cur);
int flag = 1;
while(cur<=total)
{
//下载时间
usleep(50000);
int rate = cur*100/total;
cb(rate,cur);
//假设每次下载多少
cur += 10;
//防止下载不足
if(cur>total && flag)
{
cur = total;
flag = 0;
}
}
printf("\n");
}
int main()
{
//假设进行三次下载
printf("第一次下载:\n");
downLoad(processbar);
printf("第二次下载:\n");
downLoad(processbar);
printf("第三次下载:\n");
downLoad(processbar);
return 0;
}
这个进度条的显式可以根据自己喜爱的风格再进一步完善,但主体思路就是这样
Tips:
这里一定要注意几个点
用
rate
来表示下载百分比,这里可能不是每次增加1,所以直接memset(bar, STYLE, rate)
来控制,进度多少,我们就显式多少,防止这种现象在模拟下载的时候,要对下载进度进行判断,防止下载不足
文章来源:https://www.toymoban.com/news/detail-536839.html
那本次分享就到这里的,如果有帮助的话,希望铁子们点赞支持一下,我们下期再见,如果还有下期的话。文章来源地址https://www.toymoban.com/news/detail-536839.html
到了这里,关于Linux进度条小程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!