How to set a interface in terminal using termcap library

2.1k Views Asked by At

I need to create a interface in terminal using the termios.h in C. To keep it short I have to create a executable like ./exec and after I run, it has to stop displaying the PS1 variable. If I have a program which displays the following text Hello World that uses printf it will look like:

$:> ./exec
Hello World!

But instead of printing that, I need only the Hello World! to be in the terminal, like when you clear the screen while the program is displaying.

Hello World!

To say it in other way, the purpose is to clean the terminal, and when the ./exec is runned, it should clear this line as well, $:> ./exec.

So far I managed to make this function

void    clear_screen()
{
    char buf[1024];
    char *str;

    tgetent(buf, getenv("TERM"));
    str = tgetstr("cl", NULL);
    fputs(str, stdout);
}

Which clears the screen but it keeps the line with the command itself $:> ./exec. I am not allowed to use ncurses.h library.

Here is a main:

int main(void)
{
    clear_screen();
    printf("Hello World!\n");
    return (0);
}
2

There are 2 best solutions below

8
On
printf("\033[2J"); // clear screen
printf("\033[H"); // cursor home

If you want to do anything with the screen, this is one way. You can look up other codes from 'some programmer dude's comment. You can also google vt100 codes.

There are libraries that abstract this like Ncurses but since you can't use that (why?) that's out - I'll let others elaborate on that though, maybe there are others that are allowed..

edit

try this:

printf("\033[1A\r\033[2K");

See my comment.

the VT100 codes don't help either

If you want to do anything with the screen vt100 codes are like a hacker's dream come true. Run, if you see the DEA coming, they are that good.

0
On

Something was omitted from the question (and it confuses termcap with termios). Since the sample code uses termcap, answers should address that. To recap, here's a complete example:

#include <stdio.h>
#include <stdlib.h>
#include <termcap.h>    /* this comes from ncurses, anyway... */

static void clear_screen(void)
{
    char buf[1024];
    char *str;

    tgetent(buf, getenv("TERM"));
    str = tgetstr("cl", NULL);
    fputs(str, stdout);
}

int main(void)
{
    clear_screen();
    printf("Hello World!\n");
    return (0);
}

The "cl" capability is what matters. It is defined as the corresponding feature to terminfo clear:

   clear_screen                  clear      cl        clear screen and
                                                      home cursor (P*)

If you run that example from the command-line with a correctly written terminal description, the output does this:

  • clear the entire display,
  • move the cursor to the home-position
  • print a message (which would be on the first line of the screen)
  • exit

After that, the shell prints its prompt again.

There's a couple of problems with the example:

  • it is using fputs for output. terminfo/termcap data could include padding, which won't work with that. You won't notice that with common terminal emulators' terminal description, but it matters for hardware terminals. The vt100 termcap would have this, for instance (the "50" is padding):
    :cl=50\E[H\E[J:

The proper function to use would be tputs. It happens to be in an overlapping set of functions between termcap and terminfo. In ncurses, the complete description is in the terminfo manual page.

  • some terminals (Microsoft telnet used to be a good example, though no one's tested recently...) didn't treat the control sequence properly. IN the previous example, one might have used
    :cl=\E[J\E[H

to demonstrate this: the terminal didn't clear the whole screen, but only the remainder. To work around this, the terminal descriptions were modified to move the cursor first.