简体   繁体   中英

How is erasing output in terminal implemented in C?

Some applications running in terminal can erase their outputs. eg when it tells you to wait, it will show a sequence of dots alternating between different lengths.

How is erasing output in terminal implemented in C? Is it done by reverse line feed?

Can a program only erase the previous characters in the current line, not the characters in the previous line in stdout?

Thanks.

It depends on the terminal.

The COMSPEC shell on Windows (often called the DOS prompt or command.com) exposes an API in C to control the cursor. I haven't done any Windows programming so I can't tell you much about it.

Most other terminals (especially on unixen) emulate protocols that resemble the VT100 serial terminal (the VT100 terminal was a physical device, a monitor and keyboard, that you attached to a modem or serial port to communicate with a server).

On VT100 terminals, carriage return and line feed are separate commands, both one byte. The carriage return command sets the cursor to the beginning of the line. The line feed command moves the cursor down a line (but doesn't bring the cursor to the beginning of the line by itself). Most shells on unixen automatically insert a carriage return after a line feed but almost none inserts a line feed after a carriage return.

With this knowledge, the simplest implementation is to simply output a carriage return and reprint the entire line:

printf("\rprogress: %d percent  ", x);

Note the extra spaces at the end of the line. Printing "\\r" doesn't erase the line so reprinting over the old line may end up leaving some of the old string on screen. The extra spaces is used to try and erase the remainder of the old line.

If you googled "VT100 escape secquence" , you'll find commands that will allow you to do things like erase the current line, change color of text, goto a specific row/column on screen etc. The most popular use of VT100 sequences is to output coloured text. But you can also do other things with them.

The next simplest implementation is to cleanly delete the line and reprint it:

printf("\033[2K\rprogress: %d percent", x);

The \\033[2K is the escape sequence to delete the current line (ESC[2K).

From here you can get more creative if you want. You can use the cursor save/restore command with the erase until end of line command to only erase the part you want to update (instead of the entire line). You can use the goto commands to put the cursor in a specific location on screen to update text there etc.

It should be noted that the more advanced stuff such as VT102 sequences or some of the full ANSI escape sequences are generally not portable accross terminals (by terminals I don't mean the shell, I mean the terminals: rxvt, xterm, linux terminal, hyperterminal(on windows) etc).

If you want portability (and/or sane API) you should use the curses or ncurses libraries.

If you wanted to know how it's done, then that's how it's done. It's just printing specially formatted strings to screen (except for the COMSPEC shell). Kind of like HTML but old-school.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM