Linux中的软件安装进度条怎么搞?

系统 Linux
我们在平时的服务器运维工作中,要经常安装一些软件,经常会看到下面这种进度条,本文就用C语言来实现这种进度条。

一、回车与换行

换行是换到下一行的当前位置,一般用\n表示。回车是回到当前行的开始,一般用\r表示。

但一般在语言,比如C语言中,用\n代表换行+回到开始。

二、缓冲区

先来看两段代码及其现象。

第一段代码,代码很简单,主要是为了与第二段形成对比。

#include <stdio.h>                                                                                          
#include <unistd.h>
int main()
{
printf("I am a proc\n");//有\n
sleep(3);
return 0;
}

先打印,再sleep持续3秒,很自然的结果。

第二段代码:

#include <stdio.h>                                                                                          
#include <unistd.h>
int main()
{
printf("I am a proc");//没有\n
sleep(3);
return 0;
}

第二段代码运行结果如下,从结果看来是先sleep持续3s,然后才打印。

事实上,上面的代码中由于printf在sleep之前,所以printf永远先于sleep执行,但是先执行printf不代表先打印。

printf执行后,要打印的内容放入缓冲区,但不一定会被立即刷新到屏幕上。

这里要提一下缓冲区的3种缓冲策略:

  • 1.无缓冲:数据不缓冲,直接打印到外设中(屏幕、磁盘等等)。
  • 2.行缓冲:先保存一行数据,后续刷新时按行刷新(遇到\n就把前面的内容刷新到外设)。
  • 3.全缓冲:直到把缓冲区全放满才会刷新。

再结合上面两段代码及现象,可以得出上面打印时采用的是行缓冲(遇到\n就把要打印的内容打印在屏幕上)。

三、倒计时的程序

如果每次打印完都回车,就相当于在第一个位置打印一个数字后,又回到该位置,继续打印下一个数字。这样就可以实现倒计时的效果。

#include <stdio.h>                                                                                          
#include <unistd.h>
int main()
{
int count = 3;
while(count >= 0)
{
printf("%d\r", count--);
sleep(1);
}
return 0;
}

但结果如下,并没有打印结果,想到行缓冲的规则,原来是因为打印的内容一直都没有换行,所以内容一直存在缓冲区内,不会打印出来。

这里可以用fflush函数强行让屏幕刷新,就可以实现想要的效果了。

使用fflush刷新stdout(即屏幕的文件流),使每次进入缓冲区的内容被立即打印出来。

#include <stdio.h>                                                                                          
#include <unistd.h>
int main()
{
int count = 3;
while(count >= 0)
{
printf("%d\r", count--);
fflush(stdout);
sleep(1);
}
return 0;
}

效果如下

但如果是两位或更多位的倒计时,就会出现如下的问题:

#include <stdio.h>                                                                                          
#include <unistd.h>
int main()
{
int count = 10;
while(count >= 0)
{
printf("%d\r", count--);
fflush(stdout);
sleep(1);
}
return 0;
}

因为每次回车都回到第一个字符,所以第二位的0一直没有改变。

只需用printf的格式控制即可。

#include <stdio.h>                                                                                          
#include <unistd.h>
int main()
{
int count = 10;
while(count >= 0)
{
//控制输出两位字符
printf("%2d\r", count--);
fflush(stdout);
sleep(1);
}
return 0;
}

运行效果如下:

四、进度条程序

#include <stdio.h>    
#include <string.h>
#include <unistd.h>
void ProcBar()
{
int i = 0;
char proc[102];
memset(proc, '\0', sizeof(proc));
while(i <= 100)
{
//C语言格式控制时默认右对齐,所以要在前面加-变成左对齐
printf("[%-100s] [%d%%]\r", proc, i);
fflush(stdout);//刷新屏幕打印
proc[i] = '#';
usleep(100000);//以微秒为单位的sleep
i++;
}
printf("\n");
}
int main()
{
ProcBar();
return 0;
}

责任编辑:庞桂玉 来源: 马哥Linux运维
相关推荐

2015-07-31 11:19:43

数字进度条源码

2015-01-12 12:13:03

Android进度条ProgressDia

2015-01-12 09:30:54

Android进度条ProgressDia

2024-07-25 08:55:47

进度条水缸进度动画效果

2012-07-31 09:53:33

HTML5进度条

2015-09-06 09:50:59

创业大数据

2011-07-05 15:16:00

QT 进度条

2009-04-24 08:26:02

Mobile Mark移动OS

2024-08-06 14:29:37

2015-08-03 11:39:20

拟物化进度条

2013-03-12 10:35:06

CSS 3

2012-01-17 13:58:17

JavaSwing

2023-12-11 17:15:05

应用开发波纹进度条ArkUI

2009-06-06 18:54:02

JSP编程进度条

2016-05-06 08:08:29

2024-06-13 08:15:00

2020-11-02 18:27:29

进度条Linuxcp

2023-03-06 07:25:17

LinuxAdvanced

2009-08-17 14:41:47

C#进度条实现

2009-08-18 09:49:00

C# listview
点赞
收藏

51CTO技术栈公众号