我必须在终端上编写一个自刷新进度条-表示到目前为止已复制了多少文件。我倾向于每隔1000个字节左右刷新一次输出。为了刷新屏幕,我使用了以下轮廓:

printf("\r"); // clear previous output

// output is the progress bar, percent is an integer (0 to 100)
printf("%s %d file written", output, percent);


当终端很大时,它可以正常工作。但是,如果终端很小,以至于整个进度条都无法放入其中,则回车不起作用。它仅清除视觉上的单行,而不清除整个行。我编写了一个示例程序来演示:

printf(
    "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghij"
    "abcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghijabcdefghi"
    "j");
printf("\rCHECK");


如下图所示,由于终端很小,因此仅删除整个打印输出的一部分。

c - 如何在短宽度终端中正确实现连续刷新的进度条?-LMLPHP

放置多个回车无效。

那么,用C构建这样一个不断刷新的终端输出的好方法是什么?

我也尝试过清除屏幕(printf("\033[2J");),但对我来说不起作用。它倾向于在输出的开头插入任意数量的空格,例如,请参见图片:

c - 如何在短宽度终端中正确实现连续刷新的进度条?-LMLPHP

最佳答案

通常,判断您的消息是否已包装到终端的下一行的唯一方法是将其与终端宽度(列数)进行比较。您可以使用terminfo(3)获得该信息

#include <term.h>

int main() {
    setupterm(0, 1, 0);  /* default terminal setup from the TERM envvar */


现在,您可以访问全局var columns以了解终端上有多少列。您也可以使用putp(tigetstr("cuu1"));在终端上向上一行。因此,您可以跟踪状态消息有多长时间,并弄清楚需要多长时间才能回到开始状态。

10-08 07:35
查看更多