The cursor flashes delete in the terminal, how?

I use the following lines to display my modeling progress information in my C ++ program,

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

It works great!

But the problem is that I see that the terminal cursor continues to flash cyclically by numbers, this is very annoying, does anyone know how to get rid of this?

I saw some programs like wget or ubuntu apt, they also use a progress bar or percentages, but they don't seem to blink with the cursor problem, I wonder how they did it?

Thanks!

+5
source share
5 answers

Just suppose: try using the correct number of characters '\ b' (backspace) instead of '\ r'.

== EDIT ==

I am not a Linux shell wizard, but this may work:

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

Do not forget #include <cstdlib> or <iostream> .

+10
source

You can hide and show the cursor using the DECTCEM mode (DEC cursor resolution mode) in DECSM and DECRM :

 fputs("\e[?25l", stdout); /* hide the cursor */ fputs("\e[?25h", stdout); /* show the cursor */ 
+16
source

These applications probably use ncurses . See mvaddstr

0
source

One way to avoid the cursor blinking (as suggested) is to temporarily hide the cursor.

However, this is only part of the solution. Your program should also consider this:

  • after hiding the cursor and changing the screen to , showing the cursor again move back to the original location.
  • hiding / showing the cursor keeps the cursor from blinking significantly when your updates take only a small amount of time. If you are fortunate enough to mix this with some time-consuming process, the cursor will blink.

The proposed solution using setterm not portable; it is specific to the Linux console. And running the executable using system not needed. But even works

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

is an improvement over using setterm .

Checking the source code for wget does not find hiding escape sequences. What you see with the progress bar is that it leaves the cursor in about the same place when it does something time-consuming. The output to the terminal takes so little time that you will not notice a short rewrite of the line (by printing the carriage return, and then writing most of the line again). If it were slower, hiding the cursor would help - to the point.

By the way, this method of hiding the cursor is used in terminal drivers for some editors (vim and vile ).

0
source

The reason the cursor jumps is because stdout buffered, so you don't know how many characters are typed at any given time. The reason wget doesn't have a jumping cursor is because they actually print to stderr . Try the following:

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

This also has the advantage of not cluttering up the file if you save the rest of the output somewhere using a pipe like this:

 $ ./executable > log.data 
-1
source

Source: https://habr.com/ru/post/950942/


All Articles