天天看點

在Linux下編寫一個進度條的小程式:C和shell

寫一個簡單的進度條了解三個方面的知識:進度條的實作原理,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下的Enter鍵隻代表\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 是恢複顔色的标志

繼續閱讀