如何连续刷新屏幕并实时更新

时间:2013-08-27 06:02:12

标签: c linux terminal

我想在linux上编写一个C程序,它会不断刷新屏幕并实时更新(例如,类似于终端中的top命令)。任何人都可以指出我正确的方向。

6 个答案:

答案 0 :(得分:29)

要使其在终端类型之间保持可移植性,您需要使用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()之后重新写入窗口(如上例所示)。

答案 1 :(得分:7)

Ncurses可能是最佳选择。既然你说程序,那么ncurses,c,c ++。仔细研究所有这些。但是如果你打算做一些与“shelL”相关的东西,请选择perl。

编辑:添加到我的观点,这里有一些可以给你一个想法的模块。

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

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

window.clrtobot()

好的方法是,要求诅咒清除整个窗口。

答案 2 :(得分:6)

如果您与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 wikipediancurses会优化屏幕更改,以减少使用远程shell时遇到的延迟。

答案 3 :(得分:5)

根据您的具体情况,您可以在命令行中使用“watch”命令来获取顶部的快速视图。您还可以同时观看多个命令。

例如:

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

答案 4 :(得分:3)

除了使用ncurses库进行屏幕处理外,如果你想更新它&#34;连续&#34;并且&#34;实时&#34;你可能也想要研究定时器和信号处理。 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;
    }
}

答案 5 :(得分:3)

正如其他人所说,你可能想看一下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;
}