C语言如何创建进度条?

99ANYc3cd6
预计阅读时长 17 分钟
位置: 首页 C语言 正文

下面我将从最简单的方法开始,逐步介绍更高级、更美观的实现方式,并提供完整的代码示例。

c语言createprogress
(图片来源网络,侵删)

核心思想

控制台进度条的核心思想是:

  1. 覆盖输出:在每次更新进度时,不是在新的一行打印,而是回到当前行的开头,然后打印新的进度条内容,从而覆盖掉旧的。
  2. 动态填充:根据当前进度(一个0到1之间的浮点数)计算出已经完成的字符数量(如 ),未完成的用其他字符(如 或空格)填充。
  3. 显示百分比:在进度条旁边或下方显示当前完成百分比。

实现“回到行首”的关键函数是 \r (回车符),当你打印 \r 时,光标会移动到当前行的最左边,但不会换行,接着我们打印新的进度条,就实现了覆盖效果。


基础版(使用 \r 覆盖)

这是最经典、最简单的方法,它会打印一个类似 [#####-----] 50% 的静态进度条。

代码示例

#include <stdio.h>
#include <unistd.h> // 用于 sleep 函数 (Linux/macOS)
// #include <windows.h> // 用于 Sleep 函数 (Windows)
void simple_progress_bar() {
    int total = 100;
    int progress;
    printf("开始任务...\n");
    for (progress = 0; progress <= total; progress++) {
        // 1. 计算百分比
        float percentage = (float)progress / total * 100;
        // 2. 计算填充的 '#' 数量
        int bar_length = 50; // 进度条总长度
        int filled_length = (int)(bar_length * progress / total);
        // 3. 打印进度条
        // \r 将光标移到行首
        printf("\r[");
        for (int i = 0; i < bar_length; i++) {
            if (i < filled_length) {
                printf("#");
            } else {
                printf("-");
            }
        }
        printf("] %.2f%%", percentage);
        // 4. 刷新输出缓冲区,确保立即显示
        fflush(stdout);
        // 5. 模拟任务耗时
        // Windows: Sleep(50);
        usleep(50000); // 50毫秒 (Linux/macOS)
    }
    printf("\n任务完成!\n");
}
int main() {
    simple_progress_bar();
    return 0;
}

代码解析

  1. #include <stdio.h>: 包含标准输入输出库。
  2. #include <unistd.h>: 在Linux/macOS系统下提供 usleep 函数,用于暂停程序执行,在Windows上,你需要包含 <windows.h> 并使用 Sleep() 函数(注意首字母大写,参数单位是毫秒)。
  3. printf("\r[..."): 这是关键。\r 是回车符,它把光标移到当前行的起始位置,这样接下来的输出就会覆盖掉这一行原有的内容。
  4. for 循环填充字符: 根据计算出的 filled_length,打印 代表已完成, 代表未完成。
  5. fflush(stdout): 默认情况下,printf 会将内容输出到缓冲区,只有当缓冲区满或遇到换行符时才会真正刷新到屏幕。fflush(stdout) 强制立即将缓冲区内容输出,这样我们才能看到实时的更新,而不会等到循环结束。
  6. usleep(50000): 模拟一个耗时操作,让进度条能够以肉眼可见的速度移动。

增强版(旋转光标)

这是一个更生动的版本,通过一个旋转的字符(如 \, , , )来表示程序正在“忙碌”。

c语言createprogress
(图片来源网络,侵删)

代码示例

#include <stdio.h>
#include <unistd.h>
void spinning_cursor_progress() {
    const char* cursor = "\\|/-";
    int i = 0;
    int total = 100;
    int progress;
    printf("正在处理,请稍候...\n");
    for (progress = 0; progress <= total; progress++) {
        printf("\r%c 正在处理... %.2f%%", cursor[i % 4], (float)progress / total * 100);
        fflush(stdout);
        i++;
        usleep(50000);
    }
    printf("\n处理完成!\n");
}
int main() {
    spinning_cursor_progress();
    return 0;
}

代码解析

  1. *`const char cursor = "\|/-";`**: 定义一个包含旋转字符的字符串。
  2. cursor[i % 4]: 通过 i 对4取模,可以循环地取出这四个字符,创造出旋转的视觉效果。

跨平台优化版

为了使你的代码能在Windows和Linux/macOS上无缝编译和运行,可以使用预处理指令来选择正确的头文件和函数。

代码示例

#include <stdio.h>
// 定义跨平台的睡眠函数
#ifdef _WIN32
    #include <windows.h>
    #define SLEEP(ms) Sleep(ms)
#else
    #include <unistd.h>
    #define SLEEP(ms) usleep((ms) * 1000)
#endif
void cross_platform_progress_bar() {
    int total = 100;
    int progress;
    printf("开始跨平台任务...\n");
    for (progress = 0; progress <= total; progress++) {
        float percentage = (float)progress / total * 100;
        int bar_length = 40;
        int filled_length = (int)(bar_length * progress / total);
        printf("\r[");
        for (int i = 0; i < bar_length; i++) {
            if (i < filled_length) {
                printf("=");
            } else {
                printf(" ");
            }
        }
        printf("] %.1f%%", percentage);
        fflush(stdout);
        SLEEP(50); // 使用我们定义的跨平台宏
    }
    printf("\n跨平台任务完成!\n");
}
int main() {
    cross_platform_progress_bar();
    return 0;
}

代码解析

  1. #ifdef _WIN32: 这是一个预处理指令,如果编译器定义了 _WIN32 宏(通常在Windows上编译时会定义),那么编译 #include <windows.h>#define SLEEP(ms) Sleep(ms)
  2. #else: 如果不是Windows环境(通常是Linux或macOS),则编译 #include <unistd.h>#define SLEEP(ms) usleep((ms) * 1000),注意 usleep 的单位是微秒,所以需要乘以1000来转换毫秒。
  3. SLEEP(50): 在代码中,我们使用这个自定义的 SLEEP 宏,它会自动根据操作系统调用正确的函数,代码因此变得简洁和可移植。
方法 优点 缺点 适用场景
基础版 (\r) 直观,显示具体进度 进度条是静态的,不够生动 需要显示具体完成百分比的任务,如文件下载、数据复制。
旋转光标版 动态,视觉上更友好 不显示具体进度,无法预估剩余时间 无法确定总任务量或时间较短的后台任务。
跨平台版 代码可移植性高,是专业开发的首选 代码稍微复杂一点 需要在不同操作系统上发布的C语言项目。

对于大多数情况,方法一(基础版)方法三(跨平台优化版) 是最常用和最实用的选择,你可以根据你的具体需求选择合适的实现方式。

c语言createprogress
(图片来源网络,侵删)
-- 展开阅读全文 --
头像
dede arclist如何调用文章内容?
« 上一篇 12-10
C语言如何使用GetSystemInfo获取系统信息?
下一篇 » 12-10

相关文章

取消
微信二维码
支付宝二维码

目录[+]