【问题标题】:Implement overlay in terminal在终端中实现覆盖
【发布时间】:2017-09-27 10:01:25
【问题描述】:

我想在终端中创建一个叠加层

此问答显示右/下显示时间

#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;
}

它是用以下方式编译的:

$ gcc time-overlay.c -ltermcap -o time-overlay

并使用它:

$ ./time-overlay &

它会显示:

                                                    2017-04-29 12:29:15

并不断更新时间。

停止:

$ fg
Ctrl+C

但是,有没有更好的方法来使用一些抽象低级调用的库(例如保存恢复光标位置或在某些行/列中打印)

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

【问题讨论】:

    标签: c terminal termcap


    【解决方案1】:

    这就是您使用 termcap 的方式(或任何提供 termcap 接口的东西,例如 ncurses):

    #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;
    }
    

    它仍然可以改进,因为从 tgetstr 返回的各种字符串保证所有终端描述都提供,当然,termcap 应用程序总是有缓冲区溢出问题需要解决.

    【讨论】:

      猜你喜欢
      • 2017-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多