Linux---进度条小程序

发布时间:2026/8/31 5:42:42

Linux---进度条小程序
前言在学习Linux编程的过程中编写一个进度条小程序是一个经典且极具教育意义的练手项目。它看似简单却涵盖了C语言中缓冲区机制、转义字符、格式化输出等多个重要知识点。本文将带你从零开始一步步理解并实现一个属于自己的进度条。一、预备知识回车与换行在正式编写进度条之前我们首先需要搞清楚两个基本概念回车Carriage Return和换行Line Feed。在日常使用电脑时我们习惯性地按下键盘上的Enter键来完成“回车换行”但实际上回车和换行是两个独立的动作回车\r将光标移动到当前行的最左侧行首换行\n将光标在竖直方向上向下移动一行水平位置保持不变在C语言中\n同时完成了回车和换行两个动作而\r则只实现回车的功能。理解这一点对于实现进度条至关重要——我们希望在原地不断更新进度显示而不是每次都换行输出。二、行缓冲区被“延迟”的打印先来看一段简单的代码#include stdio.h #include unistd.h int main() { printf(hello linux\n); sleep(3); return 0; }运行这段代码屏幕上会先打印出“hello linux”然后程序休眠3秒后退出。现在我们把\n去掉#include stdio.h #include unistd.h int main() { printf(hello linux); sleep(3); return 0; }神奇的事情发生了程序先休眠了3秒然后才在屏幕上打印出“hello linux”这是否意味着程序先执行了sleep后执行了printf当然不是——C程序永远是严格按照代码顺序执行的。真正的原因是数据并没有立即被送到屏幕上而是先被存放在了缓冲区Buffer中。缓冲区是C语言维护的一段内存默认情况下只有当程序结束时才会将缓冲区中的内容刷新flush到屏幕上。那么如何强制刷新缓冲区呢有以下几种方式使用\n换行符会触发缓冲区刷新程序正常结束自动刷新缓冲区调用fflush(stdout)手动强制刷新标准输出缓冲区我们可以通过fflush(stdout)来验证#include stdio.h #include unistd.h int main() { printf(hello linux); fflush(stdout); // 强制刷新缓冲区 sleep(3); return 0; }这次屏幕上会先打印出“hello linux”然后程序休眠3秒三、练手小项目倒计时程序有了上面的知识储备我们先来实现一个简单的倒计时程序练练手。倒计时要求从10开始每秒更新一次数字直到0且所有数字显示在同一行。#include stdio.h #include unistd.h int main() { int i 10; while (i 0) { printf(%-2d\r, i); // \r回车%-2d左对齐占2位 fflush(stdout); // 强制刷新缓冲区 i--; sleep(1); } printf(\n); return 0; }关键点解析使用\r而非\n\r让光标回到行首新数字会覆盖旧数字从而实现“原地更新”的效果使用fflush(stdout)因为\r不会自动刷新缓冲区必须手动刷新才能立即看到输出使用%-2d格式化控制数字10占两个字符位置如果只用%d从10变成9时只会覆盖第一个字符留下一个“0”的残影四、终极目标进度条小程序4.1 效果演示进度条的核心原理是用一个字符数组如#不断填充配合\r回到行首重新打印制造出进度条不断“增长”的视觉效果。4.2 完整代码实现process.h#pragma once #include stdio.h void process_v1(); void FlushProcess(double total, double current);process.c#include process.h #include string.h #include unistd.h #define NUM 101 #define STYLE # // 版本1简单进度条 void process_v1() { char buffer[NUM]; memset(buffer, 0, sizeof(buffer)); const char* lable |/-\\; int len strlen(lable); int cnt 0; while (cnt 100) { printf([%-100s][%d%%][%c]\r, buffer, cnt, lable[cnt % len]); fflush(stdout); buffer[cnt] STYLE; cnt; usleep(50000); // 50ms } printf(\n); } // 版本2可模拟下载进度的进度条 void FlushProcess(double total, double current) { char buffer[NUM]; memset(buffer, 0, sizeof(buffer)); const char* lable |/-\\; int len strlen(lable); static int cnt 0; int num (int)(current * 100 / total); for (int i 0; i num; i) { buffer[i] STYLE; } double rate current / total; cnt % len; printf([%-100s][%.1f%%][%c]\r, buffer, rate * 100, lable[cnt]); cnt; fflush(stdout); }main.c#include process.h #include stdio.h #include unistd.h double total 1024.0; double speed 1.0; void Download() { double current 0; while (current total) { FlushProcess(total, current); usleep(3000); // 模拟下载耗时 current speed; } printf(\ndownload %.2lfMB Done\n, current); } int main() { Download(); return 0; }MakefileSRC $(wildcard *.c) OBJ $(SRC:.c.o) BIN processbar $(BIN): $(OBJ) gcc -o $ $^ %.o:%.c gcc -c $ .PHONY: clean clean: rm -f $(OBJ) $(BIN)若报这个错在较老的 GCC 版本如 CentOS 7 自带的 GCC 4.8.x中默认编译标准是C89/C90或gnu90可修改Makefile中结果4.3 代码深度解析1为什么用\r而不是\n进度条需要在一行中不断更新如果使用\n每打印一次就会换一行产生“滚屏”效果。而\r让光标回到行首下一次打印会覆盖上一次的内容从而实现动态更新的视觉效果。2为什么每次都要fflush(stdout)\r不会触发缓冲区刷新。如果不手动刷新数据会一直待在缓冲区里直到程序结束才一次性输出——那样我们就看不到动态的进度效果了。3旋转光标lable数组的作用const char* lable |/-\\;这个数组中的四个字符|、/、-、\轮流出现模拟出一个旋转的“小转盘”让进度条看起来更生动。4usleep的作用usleep(50000)表示休眠50,000微秒即50毫秒控制进度条更新的速度。太快了看不清太慢了显得卡顿。5版本2的设计思路版本2的FlushProcess函数将进度条封装成了一个可复用的模块——传入总大小和当前已完成的大小函数自动计算百分比并绘制进度条。这种设计更贴近实际开发场景比如文件下载、软件安装等需要显示进度的功能。五、总结通过编写这个进度条小程序我们系统地学习了以下知识点知识点核心内容回车 vs 换行\r回车到行首\n换行到下一行行缓冲区数据先存缓冲区程序结束或刷新时才输出强制刷新fflush(stdout)手动刷新缓冲区格式化输出%-2d控制位宽和对齐方式动态更新\rfflush实现原地刷新进度条虽小却是一个“麻雀虽小五脏俱全”的经典项目。它不仅是Linux C编程的入门练习更是一个理解I/O缓冲机制和终端控制的绝佳窗口。

相关新闻

用C# WinForms开发定时自动清理过期文件的小工具

用C# WinForms开发定时自动清理过期文件的小工具

2026/8/31 5:42:42

简介:这是一份面向C#初学者与Windows桌面应用开发者的实用工具型资源,解决日常文件管理中临时文件、日志等周期性清理难题。用户无需编程基础,双击exe即可启动定时删除任务;开发者可基于完整源码快速定制路径、条件与日志策略。压…

吊装硬核长知识|90%老师傅都不懂的8个行业冷常识,个个都是保命干货

吊装硬核长知识|90%老师傅都不懂的8个行业冷常识,个个都是保命干货

2026/8/31 5:42:42

吊装硬核长知识|90%老师傅都不懂的8个行业冷常识,个个都是保命干货01 吊装最大隐形杀手:吊索夹角越大,载荷翻倍暴涨绝大多数吊装翻车事故,都败在忽视吊索夹角力学原理,这是最基础也最容易被忽略的核心知识点…

MATLAB App Designer开发实战:从界面搭建到Simulink联动与打包发布

MATLAB App Designer开发实战:从界面搭建到Simulink联动与打包发布

2026/8/31 5:42:42

开头如果你只是偶尔用 MATLAB 算个矩阵、画个曲线,可能永远不会觉得 MATLAB 的界面开发功能有什么价值。但如果你是做算法验证、信号处理或者科研项目,迟早会面对一个尴尬的现实:算法跑通了,模型也搭好了,却不知道该怎…

分割方向论文精读

分割方向论文精读

2026/8/31 6:52:45

一、趋势① 简单介绍:CVPR 2026 的分割方向共收录多篇相关论文,覆盖从基础模型适配、弱/无监督、视频时序、3D 与跨模态,到遥感、医学、特殊模态与评测基准的全谱系,是收录量最大的视觉子方向之一。整体呈现出「底座通用化、监督轻…

PCA数字信号故障诊断:T²与SPE统计量的MATLAB实现

PCA数字信号故障诊断:T²与SPE统计量的MATLAB实现

2026/8/31 6:52:45

简介:本资源面向本科及硕士阶段的科研与教学人员,聚焦数字信号处理中的故障诊断问题,提供基于主成分分析(PCA)的完整Matlab实现方案,适用于智能算法、信号处理等方向的课程设计、课题研究与算法验证。压缩包…

基于Spring Boot与uniapp的全开源微信小程序商城实战指南

基于Spring Boot与uniapp的全开源微信小程序商城实战指南

2026/8/31 6:52:45

简介:这是一套面向Java后端与uniapp前端开发者、专为快速构建微信小程序商城而设计的全栈开源解决方案,适用于新零售、线上网店及轻量级电商建站场景,尤其适合具备基础Web开发能力的中初级工程师学习与二次开发。资源包共2000个文件&#xff…

ICON Decomposition:面向模型审计的概念级可解释性分析与实践

ICON Decomposition:面向模型审计的概念级可解释性分析与实践

2026/8/31 6:52:45

模型训练完,内部到底在用什么特征做判断?很多人只能做两件事:看注意力热力图,或者看某些神经元的激活情况。这些方法能提供线索,却很难回答“模型是否依赖了某个概念”“多个概念是不是在联合影响输出”。这次我们来看…

Kotlin 委托:从基础语法到实战应用

Kotlin 委托:从基础语法到实战应用

2026/8/31 6:52:45

1. 引言Kotlin 的委托机制是一种强大的代码复用方式,它允许一个对象将某些行为委托给另一个对象,从而在不使用继承的情况下实现代码复用。委托在 Kotlin 中不仅体现在类层面,还体现在属性层面,甚至标准库中的 lazy、observable 等…

CNAS资质认可申报难点解析,对比CMA看实验室容易忽略的评审细节

CNAS资质认可申报难点解析,对比CMA看实验室容易忽略的评审细节

2026/8/31 6:42:45

CNAS 资质认可以 ISO/IEC 17025:2017 为核心准则,是国内实验室获取国际互认能力背书的重要途径。不少已经取得 CMA 资质认定的实验室,在申报 CNAS 资质认可时,误以为两套体系大部分内容一致,直接复用文件就可以通过评审&#xff0…

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

备战数据库管理工程师校招:索引、事务、备份恢复核心考点解析

2026/8/31 1:38:25

每年校招季我都会接触不少准备数据库方向笔试的同学,看到最多的状态就是:简历上写着“熟悉 MySQL”“了解索引优化”,一碰到数据库管理工程师的笔试卷,却在索引、事务、锁、备份恢复这些题目上翻车。网易这套 2018 校园招聘数据库…

数字电路时序基石:深入理解建立时间与保持时间

数字电路时序基石:深入理解建立时间与保持时间

2026/8/30 0:01:07

1. 这不是“背公式”的事:时间参数到底在约束什么你翻过数字电路教材,一定见过这两个词:建立时间(Setup Time)和保持时间(Hold Time)。它们常被并列写在触发器(Flip-Flop&#xff09…

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

蓝桥杯国赛超声波测距机:从单片机原理到嵌入式系统实战

2026/8/30 0:01:07

1. 项目缘起:从赛题到超声波测距机的诞生第八届蓝桥杯单片机设计与开发国赛的题目,我至今记忆犹新。它没有直接给出一个花哨的名字,而是用“超声波测距机”这个朴实无华的功能描述,精准地勾勒出了考核的核心。对于当时备赛的我而言…

MCU无DAC如何用定时器+DMA 2D输出高保真任意波形

MCU无DAC如何用定时器+DMA 2D输出高保真任意波形

2026/8/31 0:02:27

接到一个仪表类项目,要在 LAT1189 上输出几种不同波形:正弦、三角、带可调死区的脉冲,频率和幅度都得能实时改。板子上没有 DAC,就一个定时器加几个 DMA 通道。我一开始觉得在定时器中断里改比较寄存器也能应付,后来把…

Cortex-M3 Flash下载失败?从编程错误标志到供电瞬态排查

Cortex-M3 Flash下载失败?从编程错误标志到供电瞬态排查

2026/8/31 0:02:27

前两周调试一块带着Cortex-M3内核的板子,IDE里下载固件时突然弹出一行刺眼的错误: error: flash download failed - cortex-m3 。这种报错在嵌入式开发里太常见了,常见到很多人第一反应就是换根数据线、重插一下调试器,但重启三…

STM32 TouchGFX屏幕切换Transition优化:原理、配置与排障实战

STM32 TouchGFX屏幕切换Transition优化:原理、配置与排障实战

2026/8/31 0:02:27

做STM32 GUI开发的朋友应该都有体会——界面搭得再漂亮,一旦屏幕切换卡成PPT,整个产品的档次瞬间就没了。早期我在LAT1212这个基于STM32的GUI工程上用TouchGFX做二次开发,最头疼的不是画界面,而是怎么让切换动画既流畅又自然。Tou…

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

2026/8/28 7:35:26

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…

导师推荐!2026最新AI论文工具测评与实用推荐

导师推荐!2026最新AI论文工具测评与实用推荐

2026/8/28 7:34:51

2026年真正好用的AI论文工具,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

告别游戏崩溃:XCOM 2模组管理器的智能革命

告别游戏崩溃:XCOM 2模组管理器的智能革命

2026/8/28 7:34:35

告别游戏崩溃:XCOM 2模组管理器的智能革命 【免费下载链接】xcom2-launcher The Alternative Mod Launcher (AML) is a replacement for the default game launchers from XCOM 2 and XCOM Chimera Squad. 项目地址: https://gitcode.com/gh_mirrors/xc/xcom2-lau…