C 在终端中实现覆盖

C 在终端中实现覆盖,c,terminal,termcap,C,Terminal,Termcap,我想在终端中创建一个覆盖 此Q&D在右/下角显示时间 #include <stdio.h> #include <stdlib.h> #include <termcap.h> #include <termios.h> #include <error.h> #include <unistd.h> #include <time.h> static char termbuf[2048]; int main() {

我想在终端中创建一个覆盖

此Q&D在右/下角显示时间

#include <stdio.h>
#include <stdlib.h>
#include <termcap.h>
#include <termios.h>
#include <error.h>
#include <unistd.h>
#include <time.h>

static char termbuf[2048];

int main()
{
   char *termtype = getenv("TERM");

   time_t timer;
   char buffer[26];
   struct tm* tm_info;

   if (tgetent(termbuf, termtype) < 0) {
      error(EXIT_FAILURE, 0, "Could not access the termcap data base.\n");
      return 1;
   }

   int lines = tgetnum("li");
   int columns = tgetnum("co");
   int pos=1;
   while (1) {
      time(&timer);
      tm_info = localtime(&timer);
      strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
      printf("\033[s");
      fflush(stdout);

      printf("\033[%d;%dH%s\n", lines - 2, columns - 20, buffer);
      printf("\033[u");
      sleep(1);
   }
   return 0;
}
使用它:

$ ./time-overlay &
它将显示:

                                                    2017-04-29 12:29:15
并不断更新时间

停止:

$ fg
Ctrl+C
但是,对于一些抽象低级调用的库(如保存还原光标位置或在某行/列中打印),有没有更好的方法来实现这一点


我希望保留现有的终端输出(因此使用initscr()的诅咒将不起作用)

这就是您将如何使用termcap(或任何提供termcap接口的工具,例如ncurses):

#包括
#包括
#包括
#包括
#包括
#包括
#定义MAXTERM 2048
#定义EndOf(s)+strlen(s)
int
主(空)
{
char termbuf[MAXTERM];
char workbuf[MAXTERM];
char*working=workbuf;
int行、列;
字符*保存光标,*移动光标,*恢复光标;
if(tgetent(termbuf,getenv(“术语”))<0){
fprintf(stderr,“无法访问termcap数据库。\n”);
返回退出失败;
}
行数=tgetnum(“li”);
列=tgetnum(“co”);
保存光标=tgetstr(“sc”和工作);
move_cursor=tgetstr(“cm”和“工作”);
restore_cursor=tgetstr(“rc”和“工作”);
而(1){
时间计时器;
字符缓冲区[1024];
结构tm*tm_信息;
时间(&计时器);
tm_info=本地时间(&计时器);
strcpy(缓冲区、保存\光标);
sprintf(EndOf(buffer),tgoto(move_cursor,columns-20,lines-2));
strftime(EndOf(buffer),26,“%Y-%m-%d%H:%m:%S”,tm\u信息);
strcat(缓冲区、恢复\光标);
写入(文件号(stderr)、缓冲区、strlen(缓冲区));
睡眠(1);
}
返回退出成功;
}
由于并非所有终端描述都保证提供从
tgetstr
返回的各种字符串,因此它仍然可以得到改进,当然,termcap应用程序总是有缓冲区溢出问题需要解决

$ fg
Ctrl+C
#include <stdio.h>
#include <stdlib.h>
#include <termcap.h>
#include <unistd.h>
#include <string.h>
#include <time.h>

#define MAXTERM 2048
#define EndOf(s) (s) + strlen(s)

int
main(void)
{
    char termbuf[MAXTERM];
    char workbuf[MAXTERM];
    char *working = workbuf;

    int lines, columns;
    char *save_cursor, *move_cursor, *restore_cursor;

    if (tgetent(termbuf, getenv("TERM")) < 0) {
        fprintf(stderr, "Could not access the termcap database.\n");
        return EXIT_FAILURE;
    }

    lines = tgetnum("li");
    columns = tgetnum("co");
    save_cursor = tgetstr("sc", &working);
    move_cursor = tgetstr("cm", &working);
    restore_cursor = tgetstr("rc", &working);

    while (1) {
        time_t timer;
        char buffer[1024];
        struct tm *tm_info;

        time(&timer);
        tm_info = localtime(&timer);

        strcpy(buffer, save_cursor);
        sprintf(EndOf(buffer), tgoto(move_cursor, columns - 20, lines - 2));
        strftime(EndOf(buffer), 26, "%Y-%m-%d %H:%M:%S", tm_info);
        strcat(buffer, restore_cursor);

        write(fileno(stderr), buffer, strlen(buffer));
        sleep(1);
    }
    return EXIT_SUCCESS;
}