Command Line Interfaces

I worked with C for a while and am pretty good at simple command line interfaces. I also had a game with the curses , for terminal applications that do more than write text to stdout . However, I can’t understand where the half-point is located - applications such as wget or make have, for example, the ability to update the text that they display (for example, wget bouncing download meter and progress bar) without taking up screen.

Is this type of interface something that I should use curses for, or is there a gap between them? Preferably, it is cross-platform.

+6
source share
3 answers

You can do some simple things by simply typing backspace characters '\b' , and raw carriage returns '\r' (without newlines). Backspaces move the cursor back one character, allowing you to overwrite your output, and carriage returns will return the cursor to the beginning of the current line, allowing you to overwrite the current line.

Here is a simple progress bar example:

 int progress = 0; while(progress < 100) { // Note the carriage return at the start of the string and the lack of a // newline printf("\rProgress: %d%%", progress); fflush(stdout); // Do some work, and compute the new progress (0-100) progress = do_some_work(); } printf("\nDone\n"); 

Please note that you should only do this if you are writing the actual terminal (as opposed to redirecting to a file or channel). You can verify this with if(isatty(fileno(stdout)) { ... } . Of course, the same would be true if you used any other library, such as curses or ncurses.

+10
source

Between stdio and curses is the standard Unix / POSIX termios library. A trivial program for example, which discards a character and reads a string (note that no errors are checked):

 #include <stdio.h> #include <termios.h> #include <unistd.h> void munch_line() { int c; while ((c = getchar()) != EOF && c != '\n') ; } int main() { int fd; struct termios tio; printf("Enter something: "); tcgetattr(fileno(stdin), &tio); tio.c_lflag &= ~ECHO; tcsetattr(fileno(stdin), TCSANOW, &tio); munch_line(); putchar('\n'); } 

Remember to re-enable the echo before exiting the program;)

+4
source

If your terminal supports VT100 escape sequences , you can use them to move the cursor:

 printf("\x1b[%uD", n); /* move cursor n steps to the left */ printf("\x1b[%uC", n); /* move cursor n steps to the right */ printf("\x1b[K"); /* clear line from cursor to the right */ printf("\x1b[1K"); /* clear line from cursor to the left */ printf("\x1b[2K"); /* clear entire line */ 

Quick example ( curtest.c ):

 #include <stdio.h> int main(void) { printf("ZZZZZZZZZZ"); printf("\x1b[%dD", 10U); /* move cursor 10 steps to the left */ printf("YYYYYYYYY"); printf("\x1b[%dD", 9U); /* move cursor 9 steps to the left */ printf("XXXXXXXX"); printf("\x1b[%dD", 2U); /* move cursor 2 steps to the left */ printf("\x1b[1K"); /* clear line from cursor to the left */ printf("\r\n"); return 0; } 

If your terminal supports these escape codes, it should print

 mizo@host :~/test> gcc curtest.c mizo@host :~/test> ./a.out XYZ mizo@host :~/test> 

Windows command line does not have VT100 built-in support.

+3
source

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


All Articles