告别静态打印:Linux C 实现实时刷新进度条

很多刚接触 Linux C 编程的同学,都想做一个能在终端里动态刷新的进度条程序。这不仅能练手 C 语言基础,还能顺便搞懂\r、\n和行缓冲区这些关键概念。今天我们就从零开始,手把手实现一个可运行的进度条程序。

效果图:

一、先搞懂两个核心概念

1. 回车 \r 和换行 \n 的区别

很多人会把这两个搞混,其实它们的起源来自老式打字机:


换行 \n :把打字机的纸往上移动一行,光标留在当前位置的右边。
回车 \r :把打字机的打印头移动到当前行的最开头,不移动纸张。

在终端里,我们要实现进度条的 "原地刷新" 效果,就必须用\r。它会让光标回到行首,这样我们每

次打印新的进度,就会覆盖掉上一次的内容,实现动态更新。

2. 行缓冲区的坑

在 C 语言里,printf默认是行缓冲模式:只有遇到\n换行符,或者程序结束,缓冲区的内容才会被

真正输出到终端。

二、先练手:实现一个倒计时程序

//100秒倒计时

int main()

{

int time = 100;

while (time >= 0)

{

printf("%-3d\r", time);

Sleep(1000);

time--;

}

printf("\n");

return 0;

}

三、正式实现:进度条程序

1.简单实现

1.核心逻辑

进度条会从左到右填充 ,同时右边的百分比和旋转的加载动画也会同步更新,全程都在同一行刷新,体验非常丝滑。

1.核心操作解析

1.buffer:开辟数组

用来进行进度填充、

2.stat:旋转逻辑

3.rate:进度映射

2.业务逻辑

复制代码
//proce.h
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#define N 101
#define STATE '#'

void process();
void FlushProcess(double total, double current);
void FlushProcess(double total, double current)
{
    char buffer[N];
    const char* stat="|/-\\";
    memset(buffer, 0, sizeof(buffer));
    int len=strlen(stat);
    int num=(int)(current*100/total);
    static int cnt=0;
    for(int i=0;i<=num;i++)
    {
        buffer[i]=STATE;
    }
    double rate=current/total;
    cnt%=len;
    printf("[%-100s][%d%%][%c]\r",buffer,(int)(rate*100),stat[cnt]);
    cnt++;
    fflush(stdout);
}

int main()
{
    //process();
    double current=0;
    while(current<=total)
    {
        FlushProcess(total,current);
        usleep(3000);
        current+=speed;
    }
    printf("\n");
    printf("\ndownload %.2lfMB Done\n", current);
    return 0;
}
相关推荐
orion5716 小时前
Missing Semester Class1:course overview and introduction of shell
linux
apocelipes19 小时前
常用编程语言和库的正则表达式性能对比
c语言·c++·python·性能优化·golang·开发工具和环境
SkyWalking中文站21 小时前
认识 Horizon UI · 6/17:Trace 探索器
运维·监控·自动化运维
用户120487221611 天前
Linux驱动编译与加载
linux·嵌入式
火车叼位1 天前
写给初级开发者:SSL、SSH、HTTPS 与证书体系全解析
运维
用户805533698031 天前
Input 子系统架构:Core、Handler、Driver 三层是怎么协作的
linux·嵌入式
用户805533698031 天前
RK-Forge外设系列开篇 - 把板子从「能启动」变成「能用」:Ethernet/SPI/MMC 三个纯接线外设
linux·github·嵌入式
小猿姐1 天前
唯品会大规模数据库云原生实践:基于 KubeBlocks 管理数千实例的统一运维之路
运维·elasticsearch·云原生
七歌杜金房2 天前
我终于又有了自己的 Linux 电脑
linux·debian·mac
SkyWalking中文站2 天前
认识 Horizon UI · 5/17:3D 基础设施地图
运维·监控·自动化运维