linux小程序—进度条(动态演示)
阿里云国内75折 回扣 微信号:monov8 |
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6 |
文章目录
1. \n与\r的区别
1. linux环境下
下面的演示皆在linux环境下
\n:换行
- 在linux下使用\n后光标会来到下一行与之平行的位置
\r回车
- 在linux中,使用\r会使光标回到这一行开头的位置
2. windows环境下
- 在VS中使用\n实际上起到回车+换行的作用 \n默认为\r\n
2. 缓冲区问题
1.\n的情况
>当使用 hello world\n时发现会直接打印出 hello world
2.\r的情况
为了方便观察 使用一个休眠函数sleep使其休眠1秒发现最终什么也打印出不来
3. \n与\r的情况对比
- 对比\n与\r的两种情况实际上是因为行缓冲区的存在导致的在\n的程序中\n有刷新缓冲区的作用所以会立即显示hello world
- 而在\r的程序中在使用printf函数时每打印一个字符光标就会往后移动但是遇见\r时光标会回到该行的开头位置最后被命令行提示符覆盖掉
4. 使用fflush函数观察\r情况
- 为了刚好观察这一现象我们把fflush 函数(作用为刷新缓冲区)放入printf函数与sleep函数休眠之间
fflush(stdout
stdout为标准输出流
此时可以清楚的观察到是先运行printf函数遇见\r使光标回到该行的开头然后才被命令提示符覆盖
5. 不为\n与\r的情况
此时发现结果竟然是先休眠然后才先出来hello world
难道是执行的sleep函数 再去执行的printf函数吗
当然不是!
c语言中一定是自上而下运行的所以一定先执行printf函数在执行sleep休眠
由于hello world 没有被刷新在sleep期间hello world一直保留在缓冲区中
直到程序结束系统自动刷新缓冲区所以在休眠2秒后显示hello world
3.进度条的实现
1. printf 打印字符问题
1. 修改前
当我们使用\r 及fflush函数去实现一个从10开始显示的倒数实现
发现使用%d输出后printf函数打印出了实际上是以字符的形式体现的10可以看作是两个字符而9是一个字符所以只会替换掉字符1的位置打印出 9 0 两个字符
所以要使用%2d覆盖2个字符位置使其右对齐
2.修改后
使用%2d后使其修改两个字符若为一个字符时右对齐
2 . 注意事项
- 创建一个字符串使用\r每次输出#后返回该行的开头并在下次循环使用##替换掉#,并以此循环下去
- 使用printf(“\n”); 是为了防止最后显示的命令提示符覆盖掉输出的结果
- 使用memset进行初始化字符数组开辟101个空间是因为字符串最后以\0结尾而全部初始化为\0就不用再结尾考虑\0的问题了
- 使用%-100s 是为了让#从左开始打印并且没有打印的地方预留出空白区域
-usleep函数是以微妙为单位进行
1秒=10^6微妙 100000微秒=0.1秒 设置以0.1秒为间隔
3. 整体实现
1. makefile(自动化编译工具
1 myproc: main.c proc.c
2 gcc -o myproc main.c proc.c
3 .PHONY:clean
4 clean:
5 rm -f myproc
2. proc.c(函数的实现)
#include"proc.h"
2 #define size 101
3 void process()
4 {
5 char arr[size];
6 memset(arr,'\0',sizeof(char)*size);//全部 初始化为'\0'
7 char str[]="|/-\\";
8 int i=0;
9 for(i=0;i<=100;i++)
10 {
11 arr[i]='#';
12 printf("[%-100s][%d%%][%c]\r",arr,i,str[i%4]);
13 fflush(stdout);//刷新缓冲区
14 usleep(100000);//间隔0.1秒输出
15 }
16 printf("\n");
17 }
3.proc.h(函数的定义与头文件)
#include<stdio.h>
2 #include<unistd.h>//usleep函数
3 #include<string.h>
4. main.c(主函数)
#include"proc.h"
2 int main()
3 {
4 process();
5 return 0;
6 }