ncurse.h-基本使用

书接上回,我们探索了 termios.h 的使用实现了一个进入终端原始模式的程序。但是这样实在是麻烦,而且似乎运行得还不是很好。(因为我没有彻底的理解其的整个过程)但是实际上,在 Linux 下已经有了现成的库可以使用,它就是 ncurse.h
ncurse.h 将对终端设置的操作变成了几个小函数直接调用即可无需复杂的操作。比如我们需要进入原始模式关闭回显并转入无缓冲模式只需要:

1
2
3
raw();
noecho;
nodelay(stdscr, true);

对于开发来说非常友好。

Hello World

如果我们想用 ncurse.h 在终端上打印 Hello, world.,那也是非常简单的。
ncurse.hstd::coutprintf() 有个新的实现: printw()。它的用法和 printf() 完全相同。

1
2
3
4
5
6
7
8
9
#include <ncurses.h>

int main (int argc, char *argv[]) {
    initscr();
    printw("Hello, world.\n");
    getch();
    endwin();
    return 0;
}

这个 c 程序就可以在终端中绘制出 Hello, world. 并等待输入字符。当字符输入后就返回 shell。如图:
如图 这里介绍下这个程序:
最基本的 ncurse 程序的结构一定需要 initstr()endwin()

1
2
3
initstr();
//在这输入代码
endwin();

initscr() 清除了屏幕(终端内)并并展示了一个空白的屏幕,一个光标孤零零的在屏幕右上角,而整个程序的输入是由这个光标绘制的。
比如上面这个程序图,此时光标在 H 下面也就是第二行(y=1, x = 0) 的下面。为什么呢?因为我们在 printw 的最后使用了 \n 换行。之后的 printw()将会从光标位置开始绘制输入。
而在之后,使用 getch() 等待输入字符,否则就直接运行 endwin() 后结束程序。
至于 getch() ,它的定义是这样的:

1
#define getch() wgetch(stdscr)

是 wgetch(stdscr) 的别名,即在标准屏幕上接受字符,它的返回是 int 类型,不过也一样。

move() 和 getch()

在 ncurse 中,光标位置可以由二维坐标更改。坐标如图所示:
使用 move(y, x) 进行光标移动,注意:第一个参数是 y 第二个是 x。而我们也可以直接在指定位置打印文字,使用 mvprintw()。前两个参数也分别是 y, x。后面和 printw 一致。
这样,我们可以实现一个打印按下的按键的代号和内容的程序:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <ncurses.h>

int main(int argc, char *argv[]) {
    initscr();
    int c;
    printw("Write something(ESC to escape):");
    while ((c = getch()) != 27) {
        move(10, 0);
        printw("Keycode: %d, character: %c", c, c);
        move(0, 0);
        printw("Write something(ESC to escape):");
    }
    endwin();
    return 0;
}

我们发现在循环一轮回到第一行后输入的字符会在光标上显示 在讲 termios.h 的时候有讲到过回显,而这就是回显。关掉也非常简单,在开头加上 noecho() 就行。

refresh()

refresh() 在最初用处还不多,不过它的作用是检查窗口的更新而只更新需要的那一部分提高了响应速度和灵活性。

clear()

这个函数用于清空屏幕,它的实现就是调用了 shell 的 clear 命令,在很多时候大有用处。

实践

在了解完这些,就可以开始编写简单的 tui 程序了。比如像小人吃食物 小游戏,基本上达到可用。

参考资料

  1. NCURSES Programming HOWTO
  2. Youtube Ncurses tutorials
  3. wikipedia ncurses
萌ICP备20241614号