You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现类似top/btop的文本界面,需用哪些C/C++函数及依赖库?

实现类top/btop文本界面的C/C++工具与方法

原生系统级实现(无额外依赖)

1. 坐标定位与终端控制:ANSI转义序列 + termcap/terminfo

  • 直接用ANSI转义序列:无需任何库,通过输出控制序列实现光标定位、屏幕清整等操作:
    • 光标跳转:\033[y;xH(行在前、列在后,起始坐标为(1,1)),示例:printf("\033[5;10H定位到第5行第10列");
    • 屏幕操作:\033[2J清屏,\033[K清除当前行光标后内容
    • 光标控制:\033[?25l隐藏光标,\033[?25h显示光标
  • 兼容多终端:termcap/terminfo:系统自带库,可动态获取当前终端支持的控制序列,避免硬编码ANSI序列不兼容问题:
    #include <termcap.h>
    #include <stdio.h>
    #include <unistd.h>
    
    int main() {
        char term_buf[1024];
        char *cursor_move_seq;
        // 初始化termcap,获取当前终端类型
        tgetent(term_buf, getenv("TERM"));
        cursor_move_seq = tgetstr("cm", NULL);
        if (cursor_move_seq) {
            // 跳转至第3行第5列(tgoto参数为列、行,需减1适配0索引)
            tputs(tgoto(cursor_move_seq, 5-1, 3-1), 1, putchar);
            printf("适配多终端的定位文本");
        }
        return 0;
    }
    

2. 实时交互:终端模式切换

top/btop需要实时响应按键,需将终端从默认的规范模式切换为原始模式,用tcgetattr/tcsetattr实现:

#include <termios.h>
#include <unistd.h>

struct termios orig_termios;

void restore_terminal() {
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
}

void enable_raw_mode() {
    tcgetattr(STDIN_FILENO, &orig_termios);
    atexit(restore_terminal);
    struct termios raw_mode = orig_termios;
    // 禁用回显、行缓冲、信号触发
    raw_mode.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
    // 禁用输入处理(如回车转换行)
    raw_mode.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
    raw_mode.c_oflag &= ~OPOST;
    // 设置非阻塞输入:VMIN=0(无字符也返回),VTIME=1(等待100ms)
    raw_mode.c_cc[VMIN] = 0;
    raw_mode.c_cc[VTIME] = 1;
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw_mode);
}

之后可通过read(STDIN_FILENO, &key, 1)实时读取按键输入。

第三方库(简化开发)

1. ncurses(工业级终端UI库)

类Unix系统几乎预装,是top/htop等工具的核心依赖,完美支持坐标控制、窗口分割、颜色、键盘交互:

#include <ncurses.h>

int main() {
    initscr();          // 初始化ncurses环境
    cbreak();           // 禁用行缓冲,直接读取按键
    noecho();           // 不回显输入字符
    curs_set(0);        // 隐藏光标

    move(5, 10);        // 跳转至第5行第10列
    printw("ncurses坐标定位示例");
    
    box(stdscr, 0, 0);  // 给主窗口绘制边框
    refresh();          // 刷新屏幕显示
    getch();            // 等待按键输入
    endwin();           // 恢复终端原始状态
    return 0;
}

编译需链接库:gcc main.c -o app -lncurses

  • 扩展功能:用newwin创建子窗口实现分栏布局,start_color/init_pair配置颜色,addch输出自定义ASCII字符绘制图形。

2. tui(C++现代终端UI库)

面向C++的轻量库,采用面向对象设计,简化终端UI开发:

#include <tui/tui.h>

int main() {
    tui::Terminal term;
    term.set_cursor_visible(false);

    term.move_to(3, 7);  // 跳转至第3行第7列
    term.write("C++ TUI 文本定位");

    term.refresh();
    term.wait_for_key();
    return 0;
}

编译需链接库:g++ main.cpp -o app -ltui

核心技巧总结

  • 高效屏幕更新:避免全清屏幕,仅刷新变化区域(ncurses的wrefresh可指定窗口刷新)
  • ASCII定制绘制:直接输出ASCII字符组合实现图形,比如进度条:
    void draw_progress(int percent) {
        int filled = (percent * 50) / 100;
        printf("[");
        for (int i=0; i<filled; i++) printf("#");
        for (int i=filled; i<50; i++) printf("-");
        printf("] %d%%\n", percent);
    }
    
  • 实时渲染循环:用usleep(100000)控制100ms刷新间隔,结合非阻塞输入处理用户操作(如按q退出)

内容的提问来源于stack exchange,提问作者Marc Le Bihan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 20:17:28