关于进度条在写程序前,我们先来了解下进度条的几个小知识:
●回车与换行
●printf的缓存区
回车与换行:
我们在写作业的时候当写完一行是就要面临回车和换行的问题,只是我们平时没有注意,我们就用笔尖和纸来解释一下;
1.换行:笔没有动,把纸向上挪一行(现在的笔尖还是在最右边,想写字还要挪到右边来写);
2.回车:把笔尖挪到纸的左边界去,这样才可以开始写;
在计算机中的回车和换行就是这样的,在不同系统上有不同的表达方法:
● Unix系统下结尾只有 “换行”——“ \n ” “回车”—— “ \r ”
●Windows 系统下的“换行”和“回车”是在一起的——“ Enter ”
int i = 0;
char str[102];
memset(str, '\0', sizeof(str)/sizeof(char));
char tmp[4] = {'-', '\\', '|', '/'};
for(; i<=100; i++)
{
str[i] = '#';
printf("[%-101s][%d%%][%c]", str, i, tmp[i%4]);
printf("\n");
最后一行的代码是printf("\n");这样下来的结果就是 :
但是 当换成 printf("\r");时。画风突变:
所以,每次就是从座开始覆盖上一次的结果,这样就可以完成进度条的显示了。
printf缓存区:
str[i] = '#';
printf("[%-101s][%d%%][%c]", str, i, tmp[i%4]);
printf("\r");
usleep(50000);
// fflush(stdout);
这段代码中把fflush屏蔽后 它等0.5s后显示后面的东西,他显示时光标比#号每次快0.5秒,这个问题就体现出printf缓存区的作用;
根据冯诺依曼体系中所述,CPU一直和内存打交道,并不会和输入输出设备打交道,所以printf输出数据的时候是先向IO缓存区中写入,在满足某种条件的情况下才能刷新缓存区,保持计算机内核的效率;
● 缓存区填满
● 写入的字符中带有 ‘ \n ’
● 调用fflush手动刷新缓存区
● 调用scanf从缓存区中读取数据时也刷新缓存区
● printf语句结束时;
所以我们在写关于内存条代码时,要手动加载刷新缓存区的fflush的函数,才能使进度条成功运行
实现代码:
#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{
int i = 0;
char str[102];
memset(str, '\0', sizeof(str)/sizeof(char));
char tmp[4] = {'-', '\\', '|', '/'};
for(; i<=100; i++)
{
str[i] = '#';
printf("[%-101s][%d%%][%c]", str, i, tmp[i%4]);
printf("\r");
fflush(stdout);
usleep(50000);
}
printf("\n");
return 0;
}
Makefile的实现:
pro_bar:pro_bar.o
gcc pro_bar.o -o pro_bar
pro_bar.o:pro_bar.s
gcc -c pro_bar.s -o pro_bar.o
pro_bar.s:pro_bar.i
gcc -S pro_bar.i -o pro_bar.s
pro_bar.i:pro_bar.c
gcc -E pro_bar.c -o pro_bar.i
.PHONY:clean
clean:
rm -f pro_bar.i pro_bar.s pro_bar.o pro_bar
因为初次写Makefile 就当做练习 把C语言实现的 预处理 编译 汇编 链接的过程全写了。。。也可以一步写出:
pro_bar:pro_bar.c
gcc pro_bar.c -o pro_bar
.PHONY:clean
clean:
rm -f pro_bar