【Linux】进度条:行缓冲区、\r 与 fflush 的实战

编写一个命令行进度条程序,看起来是个小练习,但背后涉及行缓冲区 、回车与换行的区别 ,以及fflush的使用。这些概念在更深层次的 I/O 编程中会反复出现。

1. 回车与换行

先厘清两个历史概念:

  • 换行(Line Feed,\n):光标下移一行。

  • 回车(Carriage Return,\r):光标回到行首。

老式打字机时代,换行和回车是两个独立动作------打字到行尾后,先"咔嗒"推杆让滚筒转一行(换行),再手动把压字架推回左端(回车)。到了计算机终端,二者被合并为"按下回车键执行换行+回车"。但 \n 和 \r 在 C 语言中仍然保持各自独立的本意。

2. 行缓冲区

看三段代码:

代码 1:

c

复制代码
// 打印"hello\n",等3秒结束
printf("hello\n");
sleep(3);

现象:立刻显示"hello",然后等3秒。\n 触发了行缓冲刷新。

代码 2:

c

复制代码
// 打印"hello",等3秒结束
printf("hello");
sleep(3);

现象:3 秒内屏幕无任何输出,3 秒后程序结束才显示"hello"。因为输出被暂存在行缓冲区里,等到程序结束或缓冲区满才刷新。

代码 3:

c

复制代码
// 打印"hello",手动刷新
printf("hello");
fflush(stdout);
sleep(3);

现象:立刻显示"hello"。fflush(stdout) 强制刷新标准输出缓冲区。

3. 倒计时程序

理解了行缓冲和 \r,就可以写一个简易倒计时:

c

复制代码
int i = 10;
while (i >= 0) {
    printf("%2d\r", i);   // \r 回到行首,覆盖之前的数字
    fflush(stdout);        // 立刻输出
    i--;
    sleep(1);
}
printf("\n");

\r 把光标拉回行首,下一次 printf 会覆盖同一行上的旧内容,形成就地倒计时的视觉。

4. 进度条代码

把倒计时的思路扩展成进度条,可以做到在调用方处理下载或计算任务时实时刷新进度:

c

复制代码
void FlushProcess(double total, double current) {
    char buffer[101] = {0};
    static const char* label = "|/-\\";
    static int cnt = 0;
    int len = strlen(label);

    int num = (int)(current * 100 / total);
    for (int i = 0; i < num; i++)
        buffer[i] = '=';

    double rate = current / total;
    cnt %= len;
    printf("[%-100s][%.1f%%][%c]\r", buffer, rate * 100, label[cnt]);
    cnt++;
    fflush(stdout);
}

%-100s 表示左对齐占据100个字符宽度,不足处用空格填充。旋转字符 |/-\\ 通过循环索引给出动画效果。每次调用 FlushProcess 刷新同一行,形成连续推进的视觉效果。

usleep(50000) 即 50 毫秒的延迟,让动画不至于闪得太快。实际项目中用不到 usleep,这里只是为了人眼能看清过程。

相关推荐
数字新视界6 小时前
一体化机柜在数据中心运维中的创新应用与优势分析
大数据·服务器·数据库·动环监控系统·动力与环境监控系统
IT_陈寒6 小时前
Java静态变量初始化坑得我头皮发麻
前端·人工智能·后端
天外飞雨道沧桑7 小时前
我在浏览器里练了一个 792 参数的大模型,它学会了补全 JavaScript
开发语言·javascript·ai·ecmascript·ai编程
hhhjhl7 小时前
Yup 跨端三方库仓颉适配全流程
java·开发语言
步行cgn7 小时前
Thymeleaf 编辑表单详解:从字段回填到模拟 PUT 请求
后端
运维行者_7 小时前
网络监控工具怎么选?从设备监控到智能运维的能力清单
运维·服务器·开发语言·网络·人工智能·支持向量机·php
小小de风呀7 小时前
de风——【从零开始学习Linux】(九):进程基础 —— 从冯诺依曼体系到 fork 创建进程
linux·学习
2401_868534787 小时前
陈冲2026年上海纽约大学全英文毕业演讲
服务器·网络
挖井观天7 小时前
《Java数据结构》第一讲:顺序表
数据结构