写一个简单的进度条了解三个方面的知识:进度条的实现原理,Linux下的回车,以及缓冲区
(1)进度条的实现原理:定义一个102的字符数组bar[102],首先第一个位置bar[0] ='\0',在while循环中:每次更新从0的位置开始写入n 个‘*’(每次从开始位置写入 涉及到回车问题),更新到100结束,n来控制进度条的进度或者写入多少个*。
(2)Linux下的回车问题:
Unix 系统里,每行结尾只有“<换行>”,即“\n”;Windows系统里面,每行结尾是“<回车><换行>”,即“ \r\n”;Mac
系统里,每行结尾是“<回车>”。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成
一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。
在windows系统中,当你输入回车时会自动变成\r\n;在linux下的回车键只代表\n。
(3)缓冲区:
全缓冲:linux下默认为8192字节,在缓冲区满或者显示调用刷新函数后进行IO系统调用操作,
普通磁盘文件通常使用全缓冲区访问。
行缓冲区:默认大小为128字节,当在遇到换行符或者缓冲区满时,标准IO库执行IO系统调用操作,终端即行缓冲区。
非缓冲区:标准IO库不对字符进行缓存,标准出错流stderr通常是不带缓冲区的。
用printf()输出时是先输出到缓冲区,然后再从缓冲区送到屏幕上。Linux下缓冲区刷新到屏幕的方式:
1使用fflush(stdout)强制刷新标准输出缓冲区。
2.缓冲区已满。
3.scanf()要在缓冲区里取数据时会先将缓冲区刷新。
4.\n进入缓冲区时。
5. 程序结束时。
下面实现进度条:
#include<stdio.h>
#include<unistd.h>
int main()
{
int i=0;
char bar[102];
const char *label ="-\\|/";
bar[0] = '\0';
while(i<=100)
{
printf("[%-101s][%d%%][%c]\r",bar,i,label[i%4]);
fflush(stdout);
bar[i++] = '#';
bar[i] = '\0';
sleep(1);
}
printf("\n");
return 0;
}
makefile:
bar:bar.c
gcc -o bar bar.c
.PHONY:clean
clean:
rm -f bar
shell脚本实现一个进度条
最近学习了shell脚本语言,现在用shell脚本语言实现同一样的进度条。
首先介绍一个下在脚本语言和C语言在编写进度条的一个区别
shell脚本语言中:
printf 是一个命令语句,在bash中执行时,是fork一个子进程,运行这个命令,命令结束后,子进程退出,然后缓存区直接刷新。
而在C语言中始终在一个进程中运行,所以得用fflush刷新缓存区
直接贴代码吧,有上面的基础+shell脚本基本的语法,很容易理解
#!/bin/bash
color=(31 33 35 32 34 36)
col_idx=0
i=0
str=""
laber=('|' '/' '-' '\\')
idx=0
while [ $i -le 100 ]
do
str+='#'
#printf "[%-100s] [%d%%] [%c]\r" "$str" "$i" ${laber[$dix]}
printf "[\e[1;%dm%-100s]\e[0m [%d%%] [\e[1;31m%c\e[0m]\r" "${color[$col_idx]}" "$str" "$i" "${laber[$idx]}"
let i++
let idx++
let col_idx++
let idx%=4
let col_idx%=6
usleep 100000
done
printf "\n"
脚本中第二个printf是加了颜色的,
printf可以对输出的内容进行修改颜色,
printf"\e[字背景颜色;字体颜色m 字符串 \e[0m"
\e[0m 是恢复颜色的标志