C语言实现终端双行动态刷新加载进度条的方法
双行动态刷新终端进度条实现方案
原代码的问题在于把固定提示文本和动态进度都放在循环内的同一次打印逻辑里,直接在字符串中加\n会导致每轮循环都重复输出固定文本并换行,必然出现逐行追加的问题,没法实现动态刷新。
实现思路
- 固定显示的第一行文本只在循环启动前打印一次,打印完成后换行,将光标移动到第二行
- 循环内仅处理第二行的进度刷新:每次刷新前先将光标移回第二行行首,清除当前行残留的旧进度内容,再打印新的进度值
- 所有控制逻辑用通用ANSI转义序列实现,不需要引入第三方依赖,兼容绝大多数主流终端(Linux/macOS原生终端、Windows Terminal、PowerShell 7+等)
用到的ANSI转义序列
\r:将光标移动到当前行的行首\033[K:清除从光标位置到当前行末尾的所有内容,避免不同长度的进度文本残留\033[<行号>;<列号>H:直接将光标移动到终端指定坐标,行号、列号从1开始计数,用这个可以避免光标意外错位导致的刷新异常
注意:如果使用老版本Windows自带的cmd终端,需要先在程序初始化时调用
system("")激活ANSI转义序列支持,否则转义符会被当成普通字符打印。
修正后的可运行代码
#include <stdio.h> // 演示效果需要的延时头文件,正式使用可删除 #include <unistd.h> int main (){ // 循环外仅打印一次固定的第一行内容,打印后换行到第二行 printf("DOING THIS thing ...\n"); fflush(stdout); for (float i = 0; i <= 10000; i++){ // 定位到第二行第1列,清除行内残留后打印最新进度 printf("\033[2;1H\033[KIn progress %.2f%%", i/100); fflush(stdout); // 演示用延时,控制刷新速度,正式使用可删除 usleep(100); } // 进度完成后换行,避免后续命令行输出跟在进度行末尾 printf("\n"); return 0; }
如果确定循环内不会输出其他换行内容,也可以把循环内的打印逻辑简化为printf("\r\033[KIn progress %.2f%%", i/100);,运行效果完全一致。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

