8

我使用以下几行在我的 c++ 程序中输出模拟的进度信息,

double N=0;
double percent=0;
double total = 1000000;
for (int i; i<total; ++i)
{
    percent = 100*i/total;
    printf("\r[%6.4f%%]",percent);
}

它工作正常!

但是问题是我看到终端光标一直在数字中循环闪烁,这很烦人,有谁知道如何摆脱这个?

我见过一些程序,如 wget 或 ubuntu apt,它们也使用进度条或百分比,但它们似乎没有光标闪烁的问题,我想知道它们是怎么做到的?

谢谢!

4

6 回答 6

21

DECTCEM您可以在 和 中使用(DEC 文本光标启用模式)模式隐藏和显示DECSM光标DECRM

fputs("\e[?25l", stdout); /* hide the cursor */

fputs("\e[?25h", stdout); /* show the cursor */
于 2012-06-12T10:45:56.797 回答
12

只是一个猜测:尝试使用适当数量的“\b”(退格)字符而不是“\r”。

== 编辑 ==

我不是 Linux shell 向导,但这可能有效:

system("setterm -cursor off");
// ...display percentages...
system("setterm -cursor on");

不要忘记#include <cstdlib><iostream>

于 2012-06-11T21:55:29.960 回答
1

避免光标闪烁的一种方法是(如建议的那样)暂时隐藏光标。

然而,这只是解决方案的一部分。您的程序还应考虑到这一点:

  • 隐藏光标并修改屏幕后,再次显示光标之前其移回原始位置。
  • 隐藏/显示光标仅在您的更新只需要很短的时间时才使光标不会明显闪烁。如果您碰巧将此与一些耗时的过程混合在一起,您的光标闪烁。

建议使用的解决方案setterm是不可移植的;它特定于 Linux 控制台。并且运行一个可执行文件 usingsystem并不是真正必要的。但即使跑步

system("tput civis");
...
system("tput cnorm");

是对使用的改进setterm

检查源代码wget没有找到任何隐藏光标的转义序列。您在进度条中看到的是,每当它执行一些耗时的操作时,它会将光标留在大致相同的位置。到终端的输出只需要很少的时间,以至于您不会注意到该行的瞬时重写(通过打印回车,然后重新写入大部分行)。如果速度较慢,那么隐藏光标会有所帮助——在一定程度上。

顺便说一句——这种光标隐藏技术在某些编辑器(vim 和vile)的终端驱动程序中使用。

于 2016-08-23T21:13:41.943 回答
0

这些应用程序可能正在使用ncurses。见mvaddstr

于 2012-06-11T21:42:31.097 回答
-1

光标跳来跳去的原因是因为stdout被缓冲了,所以你实际上不知道在某个时间点打印了多少个字符。wget没有跳跃光标的原因是它们实际上是打印到的stderr,而不是无缓冲的。尝试以下操作:

fprintf(stderr, "\r[%6.4f%%]", percent);

如果您使用管道将其余输出保存在某处,这也具有不会使文件混乱的优点,例如:

$ ./executable > log.data
于 2017-07-23T05:55:40.087 回答
-2

按插入键...如果不起作用,请按键盘上的fn键。这肯定会工作
希望这会有所帮助

于 2018-10-03T14:44:06.473 回答