一、ANSI 转义序列终端色彩与光标控制Linux 终端支持 ANSI 转义序列可以实现文字着色、光标移动、清除行等高级效果是美化进度条的基础。1.1 常用颜色码前景色颜色代码颜色代码黑色30红色31绿色32黄色33蓝色34紫色35青色36白色371.2 常用光标 / 清屏控制\033[K清除光标位置到行尾的内容\033[2K清除整行内容\033[nA光标向上移动 n 行\033[nB光标向下移动 n 行二、版本 4彩色动态进度条加入绿色进度条、百分比高亮、完成后变色提示视觉效果大幅提升。#include iostream #include unistd.h #include string const int BAR_LEN 50; // ANSI 颜色宏 #define COLOR_GREEN \033[32m #define COLOR_YELLOW \033[33m #define COLOR_RED \033[31m #define COLOR_RESET \033[0m int main() { for (int i 0; i 100; i) { int fill i * BAR_LEN / 100; std::cout \r COLOR_GREEN [; // 填充部分用绿色 for (int j 0; j fill; j) { std::cout ; } // 箭头用黄色 if (fill BAR_LEN) { std::cout COLOR_YELLOW ; } // 空白部分重置颜色 std::cout COLOR_RESET; for (int j fill 1; j BAR_LEN; j) { std::cout ; } // 百分比数字高亮 if (i 100) { std::cout COLOR_GREEN ] i % 完成 COLOR_RESET; } else { std::cout ] COLOR_YELLOW i % COLOR_RESET; } std::cout.flush(); usleep(40000); } std::cout std::endl; return 0; }三、版本 5带速度与剩余时间估算的进度条模拟真实任务场景加入已处理量 / 总量、处理速度、预计剩余时间ETA是工程中最实用的版本。#include iostream #include unistd.h #include time.h #include string const int BAR_LEN 40; #define COLOR_GREEN \033[32m #define COLOR_YELLOW \033[33m #define COLOR_CYAN \033[36m #define COLOR_RESET \033[0m int main() { const int total 200; // 模拟总任务量 time_t start_time time(NULL); for (int i 0; i total; i) { // 计算进度百分比 double percent (double)i / total * 100; int fill (int)(percent * BAR_LEN / 100); // 计算速度和剩余时间 time_t now time(NULL); double elapsed difftime(now, start_time); double speed (elapsed 0) ? (i / elapsed) : 0; int eta (speed 0) ? (int)((total - i) / speed) : 0; // 输出进度条 printf(\r COLOR_GREEN [ COLOR_RESET); for (int j 0; j fill; j) printf(); if (fill BAR_LEN) printf(COLOR_YELLOW COLOR_RESET); for (int j fill 1; j BAR_LEN; j) printf( ); printf(] ); // 输出详细信息百分比、已完成/总量、速度、剩余时间 printf(COLOR_YELLOW %5.1f%% COLOR_RESET , percent); printf(%d/%d , i, total); printf(COLOR_CYAN %.1f 个/秒 COLOR_RESET , speed); printf(剩余: %d秒, eta); fflush(stdout); usleep(30000); // 模拟每个任务单元的耗时 } printf(\n); return 0; }实现逻辑说明速度计算速度 已完成数量 / 已用时间剩余时间估算ETA (总量 - 已完成量) / 速度使用time()函数获取系统时间difftime()计算时间差单位为秒。适合文件下载、批量处理、数据导入等真实业务场景。四、版本 6C 类封装工程版将进度条封装为ProgressBar类支持自定义样式、颜色、总长度可直接嵌入项目复用#ifndef PROGRESS_BAR_H #define PROGRESS_BAR_H #include string #include time.h class ProgressBar { public: // 构造函数总任务量、进度条宽度、样式字符 ProgressBar(int total, int width 50, char fill_char , char arrow_char ); // 更新进度传入当前已完成量 void update(int current); // 手动设置完成并换行 void finish(); // 是否已经完成 bool is_finished() const { return finished_; } private: int total_; // 总任务量 int width_; // 进度条宽度 char fill_char_; // 填充字符 char arrow_char_; // 箭头字符 int current_; // 当前完成量 bool finished_; // 是否完成 time_t start_; // 开始时间 // 格式化时间显示 std::string format_time(int seconds) const; }; #endif#ifndef PROGRESS_BAR_H #define PROGRESS_BAR_H #include string #include time.h class ProgressBar { public: // 构造函数总任务量、进度条宽度、样式字符 ProgressBar(int total, int width 50, char fill_char , char arrow_char ); // 更新进度传入当前已完成量 void update(int current); // 手动设置完成并换行 void finish(); // 是否已经完成 bool is_finished() const { return finished_; } private: int total_; // 总任务量 int width_; // 进度条宽度 char fill_char_; // 填充字符 char arrow_char_; // 箭头字符 int current_; // 当前完成量 bool finished_; // 是否完成 time_t start_; // 开始时间 // 格式化时间显示 std::string format_time(int seconds) const; }; #endif使用示例 main.cpp#include progress_bar.h #include unistd.h int main() { const int TOTAL 500; ProgressBar bar(TOTAL, 60, #, ); for (int i 0; i TOTAL; i) { bar.update(i); usleep(10000); } return 0; }编译运行g main.cpp progress_bar.cpp -o progress_bar ./progress_bar五、进阶扩展旋转等待指示器当任务总量未知、只能显示 “正在运行” 时使用旋转字符动画| / - \替代进度条。#include iostream #include unistd.h int main() { const char spinner[] {|, /, -, \\}; int idx 0; std::cout 正在处理中... ; for (int i 0; i 30; i) { // 模拟30次循环 printf(\b%c, spinner[idx % 4]); fflush(stdout); idx; usleep(150000); } printf(\b完成\n); return 0; }六、核心总结与注意事项ANSI 转义序列是 Linux 终端美化的核心所有主流终端均兼容。工程化使用时建议封装为类支持自定义样式、自动计算速度与 ETA。总量未知场景可用旋转指示器替代固定进度条。注意事项重定向输出到文件时ANSI 颜色码会变成乱码生产环境可加判断禁用颜色。进度更新不要过于频繁比如每毫秒刷新一次避免占用过多 CPU。多线程环境下使用进度条需要加锁防止输出错乱。谢谢
Linux C++ 进度条进阶美化与工程化封装
一、ANSI 转义序列终端色彩与光标控制Linux 终端支持 ANSI 转义序列可以实现文字着色、光标移动、清除行等高级效果是美化进度条的基础。1.1 常用颜色码前景色颜色代码颜色代码黑色30红色31绿色32黄色33蓝色34紫色35青色36白色371.2 常用光标 / 清屏控制\033[K清除光标位置到行尾的内容\033[2K清除整行内容\033[nA光标向上移动 n 行\033[nB光标向下移动 n 行二、版本 4彩色动态进度条加入绿色进度条、百分比高亮、完成后变色提示视觉效果大幅提升。#include iostream #include unistd.h #include string const int BAR_LEN 50; // ANSI 颜色宏 #define COLOR_GREEN \033[32m #define COLOR_YELLOW \033[33m #define COLOR_RED \033[31m #define COLOR_RESET \033[0m int main() { for (int i 0; i 100; i) { int fill i * BAR_LEN / 100; std::cout \r COLOR_GREEN [; // 填充部分用绿色 for (int j 0; j fill; j) { std::cout ; } // 箭头用黄色 if (fill BAR_LEN) { std::cout COLOR_YELLOW ; } // 空白部分重置颜色 std::cout COLOR_RESET; for (int j fill 1; j BAR_LEN; j) { std::cout ; } // 百分比数字高亮 if (i 100) { std::cout COLOR_GREEN ] i % 完成 COLOR_RESET; } else { std::cout ] COLOR_YELLOW i % COLOR_RESET; } std::cout.flush(); usleep(40000); } std::cout std::endl; return 0; }三、版本 5带速度与剩余时间估算的进度条模拟真实任务场景加入已处理量 / 总量、处理速度、预计剩余时间ETA是工程中最实用的版本。#include iostream #include unistd.h #include time.h #include string const int BAR_LEN 40; #define COLOR_GREEN \033[32m #define COLOR_YELLOW \033[33m #define COLOR_CYAN \033[36m #define COLOR_RESET \033[0m int main() { const int total 200; // 模拟总任务量 time_t start_time time(NULL); for (int i 0; i total; i) { // 计算进度百分比 double percent (double)i / total * 100; int fill (int)(percent * BAR_LEN / 100); // 计算速度和剩余时间 time_t now time(NULL); double elapsed difftime(now, start_time); double speed (elapsed 0) ? (i / elapsed) : 0; int eta (speed 0) ? (int)((total - i) / speed) : 0; // 输出进度条 printf(\r COLOR_GREEN [ COLOR_RESET); for (int j 0; j fill; j) printf(); if (fill BAR_LEN) printf(COLOR_YELLOW COLOR_RESET); for (int j fill 1; j BAR_LEN; j) printf( ); printf(] ); // 输出详细信息百分比、已完成/总量、速度、剩余时间 printf(COLOR_YELLOW %5.1f%% COLOR_RESET , percent); printf(%d/%d , i, total); printf(COLOR_CYAN %.1f 个/秒 COLOR_RESET , speed); printf(剩余: %d秒, eta); fflush(stdout); usleep(30000); // 模拟每个任务单元的耗时 } printf(\n); return 0; }实现逻辑说明速度计算速度 已完成数量 / 已用时间剩余时间估算ETA (总量 - 已完成量) / 速度使用time()函数获取系统时间difftime()计算时间差单位为秒。适合文件下载、批量处理、数据导入等真实业务场景。四、版本 6C 类封装工程版将进度条封装为ProgressBar类支持自定义样式、颜色、总长度可直接嵌入项目复用#ifndef PROGRESS_BAR_H #define PROGRESS_BAR_H #include string #include time.h class ProgressBar { public: // 构造函数总任务量、进度条宽度、样式字符 ProgressBar(int total, int width 50, char fill_char , char arrow_char ); // 更新进度传入当前已完成量 void update(int current); // 手动设置完成并换行 void finish(); // 是否已经完成 bool is_finished() const { return finished_; } private: int total_; // 总任务量 int width_; // 进度条宽度 char fill_char_; // 填充字符 char arrow_char_; // 箭头字符 int current_; // 当前完成量 bool finished_; // 是否完成 time_t start_; // 开始时间 // 格式化时间显示 std::string format_time(int seconds) const; }; #endif#ifndef PROGRESS_BAR_H #define PROGRESS_BAR_H #include string #include time.h class ProgressBar { public: // 构造函数总任务量、进度条宽度、样式字符 ProgressBar(int total, int width 50, char fill_char , char arrow_char ); // 更新进度传入当前已完成量 void update(int current); // 手动设置完成并换行 void finish(); // 是否已经完成 bool is_finished() const { return finished_; } private: int total_; // 总任务量 int width_; // 进度条宽度 char fill_char_; // 填充字符 char arrow_char_; // 箭头字符 int current_; // 当前完成量 bool finished_; // 是否完成 time_t start_; // 开始时间 // 格式化时间显示 std::string format_time(int seconds) const; }; #endif使用示例 main.cpp#include progress_bar.h #include unistd.h int main() { const int TOTAL 500; ProgressBar bar(TOTAL, 60, #, ); for (int i 0; i TOTAL; i) { bar.update(i); usleep(10000); } return 0; }编译运行g main.cpp progress_bar.cpp -o progress_bar ./progress_bar五、进阶扩展旋转等待指示器当任务总量未知、只能显示 “正在运行” 时使用旋转字符动画| / - \替代进度条。#include iostream #include unistd.h int main() { const char spinner[] {|, /, -, \\}; int idx 0; std::cout 正在处理中... ; for (int i 0; i 30; i) { // 模拟30次循环 printf(\b%c, spinner[idx % 4]); fflush(stdout); idx; usleep(150000); } printf(\b完成\n); return 0; }六、核心总结与注意事项ANSI 转义序列是 Linux 终端美化的核心所有主流终端均兼容。工程化使用时建议封装为类支持自定义样式、自动计算速度与 ETA。总量未知场景可用旋转指示器替代固定进度条。注意事项重定向输出到文件时ANSI 颜色码会变成乱码生产环境可加判断禁用颜色。进度更新不要过于频繁比如每毫秒刷新一次避免占用过多 CPU。多线程环境下使用进度条需要加锁防止输出错乱。谢谢