欢迎光临
我们一直在努力

【Linux我做主】进度条小程序深度解析

Linux下C语言进度条程序深度解析

  • 进度条小程序
    • GitHub地址
  • 前言
  • 前置知识
    • 回车换行(CR/LF)的深度解析
      • 历史渊源与技术规范
      • 在进度条/倒计时中的应用
    • 缓冲区机制的全面剖析
      • 缓冲区引入
      • 缓冲类型对比
      • 进度条开发中的关键控制
  • 进度条实现
    • 以小见大——倒计时
      • 倒计时最终效果演示
      • 错误演示
        • 位宽不够带来的影响
        • 设置位宽后不反转带来的影响
        • 不使用\\r回车带来的影响
      • 总结回顾倒计时
    • 进度条架构设计
      • 组件关系图
      • 核心数据结构
    • 版本迭代解析
      • v1版本悟原理
        • progressBar.h头文件
        • progressBar.c源文件
        • main.c调用
      • V2版本求拓展
        • progressBar.h头文件
        • progressBar.c源文件
        • main.c模拟多任务调度实现
        • 最终效果演示
    • Makefile配置要点
  • 结语

进度条小程序

GitHub地址

有梦想的电信狗

前言

​ 在Linux系统编程中,控制台交互的视觉反馈是提升用户体验的重要环节。进度条作为经典的人机交互组件,在软件安装、文件传输、数据处理等场景中具有广泛应用价值。本文将以Linux环境下C语言实现的进度条程序为切入点,深入探讨控制台输出控制、缓冲区机制、函数指针应用等核心技术。通过三个版本迭代的代码解析(基础版/V1、模拟多任务版/V2),读者将掌握从原理到实践的完整知识链路。


前置知识

回车换行(CR/LF)的深度解析

在C语言中,我们使用\\n来表示换行,这其实是C语言帮我们做了处理。实际上,回车和换行其实是两个动作。

C语言中用\\n来表示回车和换行。 在这里插入图片描述

以上图片深入阐述了回车和换行概念以及和区别。

  • \\r:回车,光标回到当前行的最开始。C语言中用\\r来表示仅回车。
  • \\n:换行,光标垂直向下移动一行,叫做换行。

历史渊源与技术规范

  • ASCII规范定义:CR(Carriage Return,\\r,ASCII 13)将光标移动到行首
  • LF(Line Feed,\\n,ASCII 10)使光标下移一行
  • Windows系统采用CRLF组合实现新行操作
  • Linux/Unix系统使用LF单独完成换行

在进度条/倒计时中的应用

printf(\”%-3d\\r\”, cnt); // 关键代码示例

此代码实现:

  • 使用%-3d保证3字符宽度左对齐
    • 3表示该值位宽为3,C语言默认为右对齐,用-来表示左对齐。
  • \\r使每次输出回到行首
  • 配合fflush(stdout)强制刷新缓冲区
  • 实现原地更新的数字倒计时效果
  • 缓冲区机制的全面剖析

    缓冲区引入

    先看如下两个例子:

    • 有换行符\\n时显示器直接刷新 在这里插入图片描述
    • 无换行符时,像是先执行了sleep再执行printf 在这里插入图片描述 经分析得知:
    • C语言中一定是按顺序执行代码的,因此一定是printf先执行,再执行sleep。
    • 那么,在sleep期间,printf函数一定已经执行完了。
    • 那么,sleep期间,hello wolrd在哪里?

    综上,hello wolrd一定是被保存起来了!!!

    保存hello wolrd,必然 需要一块内存空间,这块内存空间被称为缓冲区。

    • 缓冲区就是由C语言维护的一段内存。

    C程序运行时,默认会帮助我们打开三个输入输出流

    • stdin:标准输入
    • stdout:标准输出(默认是显示器)
    • stderr:标准错误

    C语言的默认行为是在程序退出时,再刷新缓冲区。

    printf打印消息,是向stdout输入,消息暂存在了stdout中,当我们不想让消息暂存在缓冲区中,而是想直接刷新stdout的内容到显示器时,可以使用fflush刷新,默认stdout在程序结束时刷新,使用fflush可以强制进行刷新输入输出流。

    在这里插入图片描述

    • 以下:
    • 此时printf(\”hello world\”)没有\\n
    • 使用fflush(stdout)强制将缓冲区中的数据刷新到显示器上

    在这里插入图片描述

    通过以上两个例子,我们已经对缓冲区有了一个大概的理解了。

    缓冲类型对比

    缓冲类型
    特征
    典型应用场景
    全缓冲 缓冲区满时刷新 文件操作
    行缓冲 遇到换行符或缓冲区满时刷新 终端输出(默认)
    无缓冲 立即输出 标准错误流stderr

    进度条开发中的关键控制

    • 手动刷新机制:

    fflush(stdout); // 强制立即输出缓冲区内容


    进度条实现

    以小见大——倒计时

    倒计时最终效果演示

    在这里插入图片描述

    • 代码如下:

    void test() {


    //实现一个倒计时
    int cnt = 100;
    while (cnt >= 0) {


    // printf(\”%-2d\\r\”, cnt);//使用\\r回车会导致三位数只刷新了两位数
    printf(\”%-3d\\r\”, cnt); // %3d\\r 可以实现在行的开头更新数字 -相当于反转 确保是左对齐
    fflush(stdout);
    —cnt;
    sleep(1);
    }
    printf(\”\\n\”);
    }
    int main() {


    test();
    return 0;
    }

    • 当前设置倒计时从100开始
    • 关于printf中的参数%-3d\\r的解释
      • %d的作用:表示输出数字cnt,用于显示倒计时
      • 3的作用:用于控制输出显示位宽为3,倒计时的数字是几位,位宽就设置为几。
      • -的作用:设置位宽后,C程序默认为右对齐,我们想让数字在当前行的最左侧显示,要用-实现左对齐。
      • \\r的作用:用于实现仅回车,回到当前行的开始,覆盖打印实现倒计时的效果。
    • 使用fflush(stdout)将缓冲区内的数据立即刷新出来
    • sleep(1)每隔一秒循环一次

    错误演示

    位宽不够带来的影响

    在这里插入图片描述

    • 位宽小于数字的位数时,会出现数字残余的情况。
    • 由于显示器是字符设备,只会一个一个打印字符,123实际上是1 2 3三个字符连在一起表示的
    • 以下是从10开始计数的错误例子

    在这里插入图片描述

    • 正确设置位宽即可解决。
    设置位宽后不反转带来的影响

    在这里插入图片描述

    • 不用-进行反转会导致数字不靠左显示
      • 对于倒计时来说影响甚微,但靠右显示的话,会导致进度条从右向左加载!
    不使用\\r回车带来的影响

    在这里插入图片描述

    • 不使用\\r会导致数字接连不断的出现,不符合倒计时的效果。

    总结回顾倒计时

    printf中的格式化控制参数缺一不可

    • 关于printf中的参数%-3d\\r的理解
      • %d表示输出数字cnt,用于显示倒计时
      • 3用于控制输出显示位宽为3,倒计时的数字是几位,位宽就设置为几。
      • 设置位宽后,C程序默认为右对齐,我们想让数字在当前行的最左侧显示,要用-实现左对齐。
      • \\r用于实现仅回车,回到当前行的开始,覆盖打印实现倒计时的效果。
    • 使用fflush(stdout)将缓冲区内的数据立即刷新出来

    进度条架构设计

    组件关系图

    #mermaid-svg-S5BlzE5BvCdjcwXb {font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-S5BlzE5BvCdjcwXb .error-icon{fill:#552222;}#mermaid-svg-S5BlzE5BvCdjcwXb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-S5BlzE5BvCdjcwXb .edge-thickness-norm

    赞(0)
    未经允许不得转载:171主机测评 » 【Linux我做主】进度条小程序深度解析
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址