【问题标题】:How to refresh the screen continuously and update it in real time [closed]如何连续刷新屏幕并实时更新[关闭]
【发布时间】:2013-08-29 18:22:14
【问题描述】:

我想在linux上写一个C程序,不断刷新屏幕并实时更新(例如,类似于终端中的top命令)。谁能指出我正确的方向。

【问题讨论】:

标签: c linux terminal


【解决方案1】:

要使其在终端类型之间保持可移植性,您需要使用诸如ncurses 之类的库。查看该链接,它是一个详尽的教程。

这是一个在屏幕左上角打印不断增加的数字的基本程序:

#include <stdio.h>
#include <ncurses.h>

int main (void)

{
        /* compile with gcc -lncurses file.c */
        int c = 0;
        /* Init ncurses mode */
        initscr ();
        /* Hide cursor */
        curs_set (0);
        while (c < 1000) {
                /* Print at row 0, col 0 */
                mvprintw (0, 0, "%d", c++);
                refresh ();
                sleep (1);
        }
        /* End ncurses mode */
        endwin();
        return 0;
}

这就是刷新窗口的方式。现在,如果您想像top 那样显示数据行,您显示的数据需要以有序的数据结构维护(取决于您的数据,它可能像数组或链表一样简单)。您必须根据您的逻辑要求对数据进行排序,然后在 clear()wclear() 之后重新写入窗口(如上例所示)。

【讨论】:

    【解决方案2】:

    如果你在xtermVT100下兼容,你可以使用console codes,例如:

    #include <stdio.h>
    #include <unistd.h> /* for sleep */
    
    #define update() printf("\033[H\033[J")
    #define gotoxy(x, y) printf("\033[%d;%dH", x, y)
    
    int main(void)
    {
        update();
        puts("Hello");
        puts("Line 2");
        sleep(2);
        gotoxy(0, 0);
        puts("Line 1");
        sleep(2);
        return(0);
    }
    

    您几乎可以使用转义序列执行所有操作,但 as pointed out in wikipedia:ncurses 优化了屏幕更改,以减少使用远程 shell 时遇到的延迟。

    【讨论】:

    • 你最好使用fputs(..., stdout) 而不是printf(...)
    • @LS_dev,你是对的,已编辑
    • 我指的是#define... 在mainputs 就足够了。
    • @LS_dev,如你所见gotoxy()(和许多其他序列)接收参数,fputs() 不是一个好的选择;)
    • 参考clear!小事,不重要,对不起! ;)
    【解决方案3】:

    Ncurses 可能是要走的路。既然你说的是程序,那么ncurses,c,c++。调查这一切。但是,如果您打算只做一些与“shell”相关的事情,请使用 perl。

    编辑:补充一下我的观点,这里有一些模块可以给你一个想法。

    http://metacpan.org/pod/Curses::UI::Dialog::Progress

    http://metacpan.org/pod/Smart::Comments

    window.clrtobot()
    

    此外,还呼吁使用诅咒来清除整个窗口。

    【讨论】:

      【解决方案4】:

      根据你的情况,你可以使用命令行中的“watch”命令来快速查看top。您还可以同时观看多个命令。

      例如:

      watch 'ls -l <somefile>; ps -fC <someprocess>; ./some_script'
      

      【讨论】:

        【解决方案5】:

        正如其他人所说,您可能想查看 ncurses 库。但是,如果您不需要高级格式化,也许像这样简单的东西就足够了:

        #include <stdio.h>
        #include <unistd.h>
        
        int main(void) {
            int number = 0;
            while (1) {
                ++number;
                printf("\rThe number is now %d.", number);
                fflush(stdout);
                sleep(1);
            }
            return 0;
        }
        

        【讨论】:

          【解决方案6】:

          除了使用 ncurses 库进行屏幕处理外,如果您想“连续”和“实时”更新它,您可能还需要研究计时器和信号处理。 timer_create()timer_settime() 可以让您启动计时器,然后您可以使用 sigaction() 设置处理函数来捕获 SIGALRM 信号并进行更新。

          编辑:根据要求,这是一些示例代码:

          #define TIMESTEP 200000000
          
          timer_t SetTimer(void) {
              struct itimerspec new_its;
              struct sigevent sevp;
              timer_t main_timer;
          
              sevp.sigev_notify = SIGEV_SIGNAL;
              sevp.sigev_signo = SIGALRM;
              timer_create(CLOCK_REALTIME, &sevp, &main_timer);
          
              new_its.it_interval.tv_sec = 0;
              new_its.it_interval.tv_nsec = TIMESTEP;
              new_its.it_value.tv_sec = 0;
              new_its.it_value.tv_nsec = TIMESTEP;
          
              timer_settime(main_timer, 0, &new_its, NULL);
              return main_timer;
          }
          
          void SetSignals(void) {
              struct sigaction sa;
          
              /*  Fill in sigaction struct  */
          
              sa.sa_handler = handler;
              sa.sa_flags = 0;
              sigemptyset(&sa.sa_mask);
          
              /*  Set signal handler  */
          
              sigaction(SIGALRM, &sa, NULL);
          }
          
          void handler(int signum) {
              switch (signum) {
              case SIGALRM:
                  update_stuff();    /*  Do your updating here  */
                  break;
              }
          }
          

          【讨论】:

          • 你能给出一个示例代码吗?
          • @sr01853:当然,我编辑了答案以添加示例。
          猜你喜欢
          • 2013-10-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-04-06
          • 1970-01-01
          • 1970-01-01
          • 2022-01-01
          • 2017-06-11
          相关资源
          最近更新 更多