本文使用到的工具有gcc vim make/makefile,边学习边实践,快速上手!
@TOC
【Linux】用C语言实现第一个小程序——“进度条”
首先我们补充两个小知识
1. 两个补充 1.1).makefile文件编写 先写通makefile,防止源文件被覆盖或删除
1 2 3 4 5 processbar:main.c gcc -o $@ $^ .PHONY:clean clean: rm -f processbar
![[Pasted image 20231107174117.png]] 生成可执行文件,第一步makefile文件编写完成。
1.2). 介绍休眠函数 sleep():
函数库文件<unistd.h>sleep(3) 程序休眠3秒后退出unistd.h是unix std的意思,包含了许多UNIX系统服务的函数原型。
现象 1)加‘\n’后会再显示器显示,光标闪动3秒后停止:
2)不加’\n’ 系统会休眠3秒,之后再显示器显示:
以上现象体现了c语言提供的缓冲区,2)在休眠时候就已经结束了,c语言是顺序结构,从上往下按顺序执行。输出的字符串被保存起来,因为c语言会为io函数提供一块【a.缓冲区 】,在退出时向屏幕输出。 b.【 回车与换行 】 我们平时写满一行时按enter来转向下一行,其实是两个动作,回车+换行。但事实上回车!=换行。换行指的是到当前列的下一行;而回车指的是:回到当前位置的开头位置 这也解释了为什么以往的计算机键盘enter占用了两个位置。
所以在c语言中,有以下两个命令:\r:只回车不换行 ,控制光标回到该行开始等待输入;\n:回车+换行 ,控制光标回带下一行开头位置等待输入;
fflush(stdout):将缓冲区中内容刷新到显示器中;usleep(); 以微秒时间进行休眠,可用man usleep来查看相关介绍
1.3倒计时 我们先小试牛刀,用刚才所学知识来写一个倒计时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <stdio.h> #include <unistd.h> int main () { int cnt=10 ; while (cnt>=0 ) { printf ("%-2d\r" ,cnt); cnt--; fflush(stdout ); sleep(1 ); } printf ("\n" ); return 0 ; }
2. 文件创建+链接 首先先创建所需要的文件: ①:makefile ②:processbar.h ③:processbar.c ④:main.c
配置makefile文件;
1 2 3 4 5 6 7 8 processbar:main.o processbar.o gcc -o $@ $^ main.o:main.c gcc -c main.c processbar.o:processbar.c gcc -c processbar.c .PHONY:clean clean: rm -f main.o processbar.o processbar
makefile配置成功! 注:-c:直接生成同名文件,不用生成入.o .i的中间文件 进度条可以看做一个不断递增的字符串,多一个`\n,
3. Vision 1. 入门版 Vision 1的版本由进度条 +比率 +旋转光标 构成
3.0 代码 1 2 3 4 5 6 7 8 9 10 11 #pragma once #include <stdio.h> #include <string.h> #include <unistd.h> #define MAX 101 #define Body '=' #define Head '>' void process2 () ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include "processbar.h" const char *lable="|/-\\" ; void process1 () { char buffer[MAX]; memset (buffer, '\0' , MAX); int cent=0 ; int n = strlen (lable); buffer[0 ] = Head; while (cent<MAX) { printf ("[%-100s][%d%%][%c]\r" ,buffer,cent,lable[cent%n]); buffer[cent++] = Body; buffer[cent] = Head; if (cent==MAX-1 ) buffer[cent] = Body; usleep(50000 ); fflush(stdout ); } printf ("\n" ); }
4. Vision 2 当前进度条是由自己控制的,但进度是多少?如何将进度条数据与实际情况结合 起来呢?依附于某种场景,比如应用下载:
4.1 download场景模拟 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #include "processbar.h" #include <time.h> #include <stdlib.h> #include <unistd.h> #define FILESIZE 1024*1024*1024 void download () { srand(time(NULL )^1023 ); int total = FILESIZE; while (total) { usleep(10000 ); int one = rand()%(1024 *1024 *10 ); total -= one; if (total < 0 ) total = 0 ; double rate =(download*1.0 / (FILESIZE))*100 ; printf ("rate:%f\n" ,rate); } }
模拟成功 ~~~
4.2 结合应用案例(download) 1 2 3 4 5 6 7 8 9 10 11 #pragma once #include <stdio.h> #include <string.h> #include <unistd.h> #define MAX 101 #define Body '=' #define Head '>' void process2 () ;void process2 (double rate) ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 const char *lable="|/-\\" ;char buffer[MAX] ={0 }; void process2 (double rate) { static int cent=0 ; int n = strlen (lable); if (rate<=1.0 ) buffer[0 ] = Head; printf ("[\033[4;32;44m%-100s\033[0m][%.1f%%][%c]\[%c]\r" ,buffer,rate,lable[cent%n]); fflush(stdout ); buffer[(int )rate] = Body; if ((int )rate< MAX-2 ) buffer[(int )rate+1 ] = Head; if (rate>=100.0 ) printf ("\n" ); cent++; }
4.3 字符颜色 1 printf("[\033[4;32;44m%-100s\033[0m][%.1f%%][%c]\[%c]\r",buffer,rate,lable[cent%n]);
开始 设置属性:\033[31m—> \033[31m+背景色+字体色+显示效果关闭 所有属性:\033[0m背景色 (40-47):设置背景色【40: 黑 41: 红 42: 绿 43: 黄 44: 蓝 45: 紫 46: 深绿 47: 白色】字体色( 30-37):【30: 黑 31: 红 32: 绿 33: 黄 34: 蓝 35: 紫 36: 深绿 37: 白色】
5. 文章源代码
1 2 3 4 5 6 7 8 9 processbar:main.o processbar.o gcc -o $@ $^ main.o:main.c gcc -c main.c processbar.o:processbar.c gcc -c processbar.c .PHONY:clean clean: rm -f processbar main.o processbar.o
1 2 3 4 5 6 7 8 9 10 11 12 #pragma once #include <stdio.h> #include <string.h> #include <unistd.h> #define MAX 101 #define Body '=' #define Head '>' void process2 () ;void process2 (double rate) ;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include "processbar.h" const char *lable="|/-\\" ;void process1 () { char buffer[MAX]; memset (buffer, '\0' , MAX); int cent=0 ; int n = strlen (lable); buffer[0 ] = Head; while (cent<MAX) { printf ("[%-100s[ %.3f%%][%c]\r" ,buffer,cent,lable[cent%n]); buffer[cent++] = Body; buffer[cent] = Head; if (cent==MAX-1 ) buffer[cent] = Body; usleep(50000 ); fflush(stdout ); } printf ("\n" ); } char buffer[MAX] ={0 }; void process2 (double rate) { static int cent=0 ; int n = strlen (lable); if (rate<=1.0 ) buffer[0 ] = Head; printf ("[\033[4;32;44m%-100s\033[0m][%.1f%%][%c]\r" ,buffer,rate,lable[cent%n]); fflush(stdout ); buffer[(int )rate] = Body; if ((int )rate< MAX-2 ) buffer[(int )rate+1 ] = Head; if (rate>=100.0 ) printf ("\n" ); cent++; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #define FILESIZE 1024*1024*1024 void download () { srand(time(NULL )^1023 ); int total = FILESIZE; while (total) { usleep(10000 ); int one = rand()%(1024 *1024 *5 ); total -= one; if (total < 0 ) total = 0 ; int download = (FILESIZE) - total; double rate =(download*1.0 / (FILESIZE))*100 ; process2(rate); } } int main () { download(); return 0 ; }
👀👀