【linux】进度条
发布时间 - 2025-06-26 00:00:00 点击率:次- 屏幕缓冲区
屏幕缓冲区是指在输出设备(如终端或控制台)之前,数据被临时存储的内存区域。应用程序将输出数据写入这个缓冲区,然后系统会统一将缓冲区的内容刷新到屏幕上。使用缓冲区可以提高i/o操作的效率,因为它允许数据批量刷新,而不是每次输出都进行一次i/o操作。
缓冲区的刷新模式决定了何时将缓冲区内容刷新到终端屏幕上。主要有以下几种模式:
- 全缓冲模式(Fully Buffered):数据只有在缓冲区满时才会被刷新到屏幕上,通常用于文件I/O。
- 行缓冲模式(Line Buffered):当遇到换行字符(LF,
\n)时,缓冲区内容会被刷新到屏幕上,常见于终端I/O。一些标准输出流(如stdout)在连接到终端时默认使用行缓冲模式。 - 无缓冲模式(Unbuffered):数据每次写入缓冲区后立即被刷新到屏幕上,适用于需要实时输出的场景,如错误输出流(如
stderr)通常是无缓冲的。
在屏幕缓冲区的刷新以及终端输出中,换行字符和回车字符起着重要作用:
- 换行(Line Feed,
\n):将光标移到下一行。在行缓冲模式下,遇到换行字符时,缓冲区的内容会被立即刷新到屏幕上。在许多现代终端和编程环境中,输出一个换行字符通常意味着会将当前行的数据刷新到屏幕。 - 回车(Carriage Return,
\r):将光标移动到当前行的起始位置(即行首),但不移动到下一行。常用于覆盖同一行内容,如进度条或动态日志输出。输出回车字符后,下一次的输出会从行首开始,覆盖当前行的内容。
换行和回车在屏幕缓冲区中的作用:
- 行缓冲模式:换行字符(
\n)会触发缓冲区刷新,将内容显示到屏幕上。 - 回车字符(
\r):不触发缓冲区刷新,而是移动光标,通常与手动刷新缓冲区结合使用,以实现动态行更新。
总结来说,缓冲区刷新模式(全缓冲、行缓冲和无缓冲)控制了何时将数据从缓冲区刷新到屏幕。换行字符(\n)在行缓冲模式下起到触发缓冲区刷新的作用,同时将光标移到下一行。回车字符(\r)将光标移动到行首,常用于覆盖当前行的内容,而不触发缓冲区刷新。综合使用换行和回车字符,可以实现灵活的终端输出效果,特别在实时显示和动态更新场景中非常常见。
从您提供的代码来看,您有两个几乎相同的代码块,但您希望了解的现象可能是与终端缓冲和输出可见性相关的。让我们总结并推测可能的观察现象。
代码块1:
#include#include // For sleep() int main() { printf("hello Makefile!\n"); sleep(3); return 0; }
代码块2:
#include#include // For sleep() int main() { printf("hello Makefile!"); sleep(3); return 0; }
终端输出现象:
- 代码块1:输出字符串 “hel
lo Makefile!” 后接换行符 \n。在行缓冲模式下,遇到\n立即刷新输出缓冲区内容到终端。您会立即看到 “hello Makefile!” 和换行,接下来程序会暂停3秒钟,然后退出。终端显示:
hello Makefile! (暂停3秒钟)
- 代码块2:输出字符串 “hello Makefile!”,但没有换行符
\n。在行缓冲模式下,由于没有遇到\n,缓冲区不立即刷新到终端,除非缓冲区满或者进程结束。因为接下来代码调用sleep(3)而没有刷新缓冲区,所以在大多数情况下,您在终端上可能看不到立即的输出。直到程序退出或缓冲区被手动刷新,“hello Makefile!” 的内容才会显示。终端显示:
(暂停3秒钟) hello Makefile!
如果希望在没有换行符的情况下立即刷新输出缓冲区,可以在 printf 后调用 fflush(stdout):
修改后的代码块2:
#include#include int main() { printf("hello Makefile!"); fflush(stdout); // 手动刷新标准输出缓冲区 sleep(3); return 0; }
这样做确保 “hello Makefile!” 会立即显示在终端上,不需要等到程序退出或缓冲区满。
终端显示:
hello Makefile! (暂停3秒钟)
总结:
- 带有换行符
\n的printf在行缓冲模式下会立即刷新到终端。 - 没有换行符的
printf可能不会立即刷新缓冲区,需要手动调用fflush(stdout)。 - 使用
\n或fflush(stdout)确保输出立即可见,尤其是在待运行一段时间的代码(如sleep())之后进行输出时。
这些现象主要源于终端缓冲机制的行为,在不同开发和调试环境中(特别是高速输出场景下)理解这些机制尤其有用。
- 进度条
有了上面缓冲区的知识,我们就可以实现一个简易版的进度条。
文件结构如下:
准备工作完成后,我们下面只需完成进度条的主体代码即可。
#include"Processbar.h" #include#include #define length 101 #define Style '#' void Procbar(){ char bar[101]; memset(bar,'\0',sizeof(bar)); int cnt=0; while(cnt < 100){ printf("[%-100s][%d%%]\r", bar, cnt); fflush(stdout); bar[cnt++] = Style; usleep(10000); } printf("\n"); }
进度条显示函数 Procbar:
-
char bar[length];:声明一个字符数组bar,长度为length(101 个字符),用于存储进度条的内容。 -
memset(bar, '\0', sizeof(bar));:将bar数组的所有元素初始化为\0,表示进度条初始为空。 -
int cnt = 0;:初始化一个整型变量cnt,作为进度百分比,从0开始。 while(cnt :使用while循环,将cnt从0逐步增到100,模拟从0%到100%的进度条显示。-
printf("[%-100s][%d%%]\r", bar, cnt);:格式化输出进度条。%-100s表示左对齐,宽度为100的字符串,%d%%表示当前的百分比。\r让光标返回行首。 -
fflush(stdout);:刷新标准输出,使得进度条及时更新。 -
bar[cnt++] = Style;:将bar数组的第cnt个位置设置为#,并将cnt递增1,表示进度条推进一格。 -
usleep(10000);:暂停程序10毫秒,以模拟进度条的动态效果。
-
-
printf("\n");:循环结束后,打印一个换行符,结束进度条的显示。
优化版本:
我们设置文件大小和带宽速度,这时候进度条的函数需要进行修改。
#include"Processbar.h" #includevoid download() { double filesize=100*1024*1024*1.0; double current=0.0; double bandwidth=1024*1024*1.0; printf("download begin,current: %lf\n",current); while(current < filesize){ current += bandwidth; if(current > filesize) current = filesize; Procbar(filesize,current); usleep(10000); } printf("download finished,current: %lf\n",current); }
#include"Processbar.h" #include#include #define length 101 #define Style '#' void Procbar(double total,double current) { char bar[101]; memset(bar,'\0',sizeof(bar)); int cnt=0; double rate = (current*100.0)/total; int loop_count =(int)rate; while(cnt < loop_count){ printf("[%-100s][%.2f%%]\r", bar, rate); fflush(stdout); bar[cnt++] = Style; } printf("[%-100s][%.2f%%]\r", bar, rate); fflush(stdout); }
# linux
# ai
# 格式化输出
# red
# while
# printf
# 整型
# 字符串
# char
# int
# 循环
# Length
# 进度条
# 换行
# 屏幕上
# 换行符
# 模式下
# 时将
# 移到
# 是在
# 让我们
# 才会
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Laravel如何配置和使用队列处理异步任务_Laravel队列驱动与任务分发实例
如何破解联通资金短缺导致的基站建设难题?
javascript中的数组方法有哪些_如何利用数组方法简化数据处理
jQuery中的100个技巧汇总
Laravel怎么自定义错误页面_Laravel修改404和500页面模板
Laravel观察者模式如何使用_Laravel Model Observer配置
Python文件异常处理策略_健壮性说明【指导】
如何在Tomcat中配置并部署网站项目?
消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工
深圳网站制作设计招聘,关于服装设计的流行趋势,哪里的资料比较全面?
Laravel如何保护应用免受CSRF攻击?(原理和示例)
如何在万网开始建站?分步指南解析
Linux系统命令中screen命令详解
Windows Hello人脸识别突然无法使用
如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)
Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置
油猴 教程,油猴搜脚本为什么会网页无法显示?
香港服务器租用费用高吗?如何避免常见误区?
详解CentOS6.5 安装 MySQL5.1.71的方法
详解Oracle修改字段类型方法总结
uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址
网站制作软件免费下载安装,有哪些免费下载的软件网站?
如何在宝塔面板创建新站点?
企业网站制作这些问题要关注
北京网页设计制作网站有哪些,继续教育自动播放怎么设置?
如何快速查询网站的真实建站时间?
韩国服务器如何优化跨境访问实现高效连接?
想要更高端的建设网站,这些原则一定要坚持!
php结合redis实现高并发下的抢购、秒杀功能的实例
Laravel Eloquent性能优化技巧_Laravel N+1查询问题解决
Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询
大型企业网站制作流程,做网站需要注册公司吗?
如何在阿里云域名上完成建站全流程?
如何选择可靠的免备案建站服务器?
如何快速生成专业多端适配建站电话?
长沙企业网站制作哪家好,长沙水业集团官方网站?
高端建站如何打造兼具美学与转化的品牌官网?
Laravel安装步骤详细教程_Laravel环境搭建指南
使用spring连接及操作mongodb3.0实例
新三国志曹操传主线渭水交兵攻略
lovemo网页版地址 lovemo官网手机登录
Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置
如何在不使用负向后查找的情况下匹配特定条件前的换行符
深入理解Android中的xmlns:tools属性
胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?
如何在阿里云高效完成企业建站全流程?
如何用景安虚拟主机手机版绑定域名建站?
再谈Python中的字符串与字符编码(推荐)
JavaScript如何实现继承_有哪些常用方法
java ZXing生成二维码及条码实例分享


lo Makefile!” 后接换行符