大多数 Linux 实用程序只是从屏幕底部滚动文本。但是,如果你想将文本放置在屏幕上,例如用于游戏或数据展示,该怎么办? 这就是 ncurses 发挥作用的地方。
curses 是一个古老的 Unix 库,支持文本终端屏幕上的光标控制。 名称curses来自术语光标控制。 几年后,其他人编写了一个改进版本的 curses 以添加新功能,称为new curses 或 ncurses。 你可以在每个现代 Linux 发行版中找到 ncurses,尽管默认情况下可能未安装开发库、头文件和文档。 例如,在 Fedora 上,你需要使用以下命令安装 ncurses-devel 包
$ sudo dnf install ncurses-devel
在程序中使用 ncurses
要直接寻址屏幕,首先需要初始化 ncurses 库。 大多数程序将使用以下三行代码来执行此操作
- initscr(); 初始化屏幕和 ncurses 代码
- cbreak(); 禁用缓冲并使键入的输入立即可用
- noecho(); 关闭回显,以便用户输入不会显示在屏幕上
这些函数在 curses.h 头文件中定义,你需要使用以下代码将其包含在你的程序中
#include <curses.h>
初始化终端后,你可以自由使用任何 ncurses 函数,我们将在示例程序中探讨其中的一些函数。
当你完成 ncurses 并且想要返回常规终端模式时,请使用 endwin(); 来重置所有内容。 此命令重置任何屏幕颜色,将光标移动到屏幕的左下方,并使光标可见。 你通常会在退出程序之前执行此操作。
寻址屏幕
关于 ncurses 首先要知道的是,屏幕坐标是行,列,并从左上角的 0,0 开始。 ncurses 定义了两个全局变量来帮助你识别屏幕尺寸:LINES 是屏幕上的行数,COLS 是列数。 右下角的位置是 LINES-1,COLS-1。
例如,如果你想将光标移动到第 10 行和第 30 列,你可以使用带有这些坐标的 move 函数
move(10, 30);
在此之后显示的任何文本都将从该屏幕位置开始。 要显示单个字符,请使用带有单个字符的 addch(c) 函数。 要显示字符串,请使用带有你的字符串的 addstr(s)。 对于类似于 printf 的格式化输出,请使用带有通常选项的 printw(fmt, …)。
移动到屏幕位置并显示文本是一件常见的事情,因此 ncurses 提供了一个快捷方式来同时执行这两项操作。 mvaddch(row, col, c) 函数将在屏幕位置 row,col 显示一个字符。 mvaddstr(row, col, s) 函数将在该位置显示一个字符串。 举个更直接的例子,在程序中使用 mvaddstr(10, 30, "Welcome to ncurses"); 将在第 10 行和第 30 列开始显示文本 "Welcome to ncurses"。 代码 mvaddch(0, 0, '+'); 将在左上角第 0 行和第 0 列显示一个加号。
在终端屏幕上绘制文本可能会对某些系统(尤其是在较旧的硬件终端上)产生性能影响。 因此,ncurses 允许你“堆叠”大量要显示到屏幕上的文本,然后使用 refresh() 函数使所有这些更改对用户可见。
让我们看一个将所有内容组合在一起的简单示例
#include <curses.h>
int
main()
{
initscr();
cbreak();
noecho();
mvaddch(0, 0, '+');
mvaddch(LINES - 1, 0, '-');
mvaddstr(10, 30, "press any key to quit");
refresh();
getch();
endwin();
}
该程序首先初始化终端,然后在左上角打印一个加号,在左下角打印一个减号,并在第 10 行和第 30 列打印文本“press any key to quit”。 该程序使用 getch() 函数从键盘获取一个字符,然后在程序完全退出之前使用 endwin() 重置终端。
getch() 是一个有用的函数,你可以将其用于许多事情。 我经常使用它作为在退出程序之前暂停的一种方式。 与大多数 ncurses 函数一样,也有一个名为 mvgetch(row, col) 的 getch() 版本,用于在等待字符之前移动到屏幕位置 row,col。
使用 ncurses 编译
如果你尝试以通常的方式编译该示例程序,例如 gcc pause.c
,你可能会从链接器收到一个巨大的错误列表。 这是因为 GNU C 编译器不会自动链接 ncurses 库。 相反,你需要使用 -l ncurses
命令行选项加载它以进行链接。
$ gcc -o pause pause.c -lncurses
运行新程序将打印一个简单的“press any key to quit”消息,该消息或多或少地位于屏幕的中心

图 1:程序中居中的“press any key to quit”消息。
使用 ncurses 构建更好的程序
浏览 ncurses 库函数以了解其他向屏幕显示文本的方式。 你可以在 man ncurses 手册页中找到所有 ncurses 函数的列表。 这提供了 ncurses 的一般概述,并提供了一个类似表格的 ncurses 函数列表,并引用了包含完整细节的手册页。 例如,printw 在 curs_printw(3X) 手册页中进行了描述,你可以使用以下命令查看该手册页
$ man 3x curs_printw
或者只是
$ man curs_printw
使用 ncurses,你可以创建更有趣的程序。 通过在屏幕上的特定位置打印文本,你可以创建游戏和高级实用程序以在终端中运行。
评论已关闭。