前言
先来看看我们想要达到的进度条效果,具体代码会在文章最后面放出。
一、创建文件及Makefile
我们需要实现声明的定义的分离,因此创建如下三个文件。
process.h prcess.c main.c。
bash
touch process.h process.c main.c
同时还需要创建Makefile来帮助我们构建代码。
bash
touch Makefile
vim打开Makefile进行编辑。
cpp
vim Makefile
第一行 代表mybin依赖与main.c和process.c
第二行 gcc命令,\^指第一行 ":" 右边的内容,@指 ":" 左边的内容,即等于gcc main.c process.c -o mybin。这会生成可执行文件mybin。
第三行 .PHONY声明伪目标:clean,让clean代码一直可以执行。
第四行 代表clean没有依赖任何文件
第五行 删除命令,删除 mybin
cpp
1 mybin:main.c process.c
2 gcc $^ -o $@
3 .PHONY:clean
4 clean:
5 rm -f mybin
二、第一版代码
vim process.h 打开文件进行编辑。(unistd.h是后面需要用到的休眠函数头文件)
cpp
#pragma once
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void process();
vim process.c
代码部分难度不高,重要的地方在于打印函数,printf("[%-100s][%3d%%][%c]\r",bar,rate,str[rate%num]);
-%100s代表向左保留100位打印字符串,%3d代表保留3位打印整形,\r代表只回车,就是将光标移动到最左边。
fflush(stdout)为刷新标准输出缓冲区,让缓冲区里面的内容输出在屏幕上。
usleep为休眠函数,单位为微秒。
cpp
#include "process.h"
#define SIZE 101
#define STIME 1000*40 //设置休眠
const char* str = "|/-\\"; //旋转符号
void process()
{
int rate = 0; //设置达到比率
char bar[SIZE] = {0}; //先置空
int num = strlen(str);
while(rate<=100)
{
printf("[%-100s][%3d%%][%c]\r",bar,rate,str[rate%num]);
fflush(stdout);
usleep(STIME);
bar[rate++] = '#';
}
printf("\n");
}
vim main.c 调用一下。
cpp
#include "process.h"
int main()
{
process();
}
编辑好了就wq保存并退出。
因为有了Makefile,我们在命令行直接输入make就可以完成构建了。
./mybin 执行一下就输出了。
三、第二版代码
在一版代码中,我们使用了一个函数将进度条打印完成,但真实的场景不是这样的,我们应该根据rate的更新,进行打印,rate更新了多少,我们才打印多少。
因此我们给第二个版本函数参数添加一个rate,函数里面也不需要循环了,目的是调用这个函数就打印一次,我通过外面的循环去控制rate来打印。
process.c添加如下代码
cpp
void process_v2(int rate)
{
static char bar[SIZE] = {0};
int num = strlen(str);
if(rate<=100&&rate>=0)
{
printf("[%-100s][%3d%%][%c]\r",bar,rate,str[rate%num]);
fflush(stdout);
bar[rate] = '#';
}
}
main.c添加如下代码去模拟下载
目标为target,当前下载为total,直到下载达到了target才能说我们下载完成了。
cpp
#define TARGET_SIZE 1024*1024 //需要下载的文件
#define DSIZE 1024*10
void download()
{
int target = TARGET_SIZE;
int total = 0;
while(total<=target)
{
usleep(STIME); //休眠模拟下载需要消费的时间
total+=DSIZE; //休眠(下载)完成就添加下载好的百分比
process_v2(total*100/target); //调用打印
}
printf("\n");
}
主函数再调用一下即可
由于main.c用到了process.c的宏定义,因此需要将该宏定义放到process.h里才不会报错(main.c和process.c都包了头文件process.h)
process.h修改如下
我们在make后运行一下,没啥问题。
最后附上总代码
process.h
cpp
#pragma once
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define SIZE 101
#define STIME 1000*40
void process_v1();
void process_v2(int rate);
process.c
cpp
#include "process.h"
const char* str = "|/-\\";
void process_v1()
{
int rate = 0;
char bar[SIZE] = {0};
int num = strlen(str);
while(rate<=100)
{
printf("[%-100s][%3d%%][%c]\r",bar,rate,str[rate%num]);
fflush(stdout);
usleep(STIME);
bar[rate++] = '#';
}
printf("\n");
}
void process_v2(int rate)
{
static char bar[SIZE] = {0};
int num = strlen(str);
if(rate<=100&&rate>=0)
{
printf("[%-100s][%3d%%][%c]\r",bar,rate,str[rate%num]);
fflush(stdout);
bar[rate] = '#';
}
}
main.c
cpp
#include "process.h"
#define TARGET_SIZE 1024*1024 //需要下载的文件
#define DSIZE 1024*10
void download()
{
int target = TARGET_SIZE;
int total = 0;
while(total<=target)
{
usleep(STIME); //休眠模拟下载需要消费的时间
total+=DSIZE;
process_v2(total*100/target);
}
printf("\n");
}
int main()
{
//process_v1();
download();
}
Makefile
cpp
mybin:main.c process.c
gcc $^ -o $@
.PHONY:clean
clean:
rm -f mybin
谢谢大家观看