光标在终端闪烁删除,怎么办?

时间:2012-06-11 21:01:00

标签: c++ shell terminal cursor

我使用以下行在我的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这样的程序,它们也使用进度条或百分比,但它们似乎没有闪烁的光标问题,我想知道他们是怎么做到的?

谢谢!

6 个答案:

答案 0 :(得分:18)

您可以使用DECTCEMDECSM中的DECRM(DEC文本光标启用模式)模式隐藏和显示光标:

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

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

答案 1 :(得分:11)

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

==编辑==

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

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

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

答案 2 :(得分:1)

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

然而,这只是解决方案的一部分。您的计划也应考虑到这一点:

  • 隐藏光标并修改屏幕后, 再次显示光标移动将其恢复到原始位置。
  • 隐藏/显示光标只会在您的更新只花费少量时间时使光标不会明显闪烁。如果您碰巧将此与一些耗时的过程相混合,则光标闪烁。

使用setterm的建议解决方案不可移植;它特定于Linux控制台。使用system运行可执行文件并不是必需的。但即便运行

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

比使用setterm改进了。

检查wget的源代码没有找到任何光标隐藏转义序列。你看到它的进度条就是它只要花费很多时间就把光标留在大致相同的位置。到终端的输出花费很少的时间,你没有注意到线的瞬间重写(通过打印回车,然后再次写入大部分线)。如果速度较慢,那么隐藏光标会有所帮助 - 直到某一点。

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

答案 3 :(得分:0)

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

答案 4 :(得分:-1)

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

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

如果您使用以下管道将输出的其余部分保存在某处,这样做的优点还在于不会弄乱文件:

$ ./executable > log.data

答案 5 :(得分:-1)

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