大多数Linux工具只是从屏幕的底部滚动文本。但如果你想在屏幕上定位文本,比如游戏或数据显示,该怎么办?这就是ncurses出现的地方。
curses是一个古老的Unix库,它支持文本终端屏幕上的光标控制。curses这个名字来自于光标控制这个术语。多年以后,其他人写了一个改进版的curses来增加新的功能,称为新curses或ncurses。你可以在每个现代Linux发行版中找到ncurses,尽管开发库、头文件和文档可能不是默认安装的。例如,在Fedora上,你需要用这个命令安装ncurses-devel包。
$ sudo dnf install ncurses-devel
在程序中使用ncurses
要直接处理屏幕,你首先需要初始化ncurses库。大多数程序会用这三行来完成。
- initscr(); 初始化屏幕和ncurses代码
- cbreak(); 禁用缓冲并使输入的信息立即可用
- noecho(); 关闭回声,因此用户的输入不会显示在屏幕上。
这些函数是在curses.h头文件中定义的,你需要在你的程序中包含这些函数。
#include
在初始化终端后,你可以自由地使用任何ncurses函数,我们将在一个示例程序中探讨其中的一些。
当你用完ncurses并想回到常规的终端模式时,使用**endwin();**来重置一切。这个命令重置了所有的屏幕颜色,将光标移到屏幕的左下方,并使光标可见。你通常在退出程序前做这个动作。
对屏幕的寻址
关于ncurses的第一件事是,屏幕坐标是row,col,从左上角的0,0开始。ncurses定义了两个全局变量来帮助你确定屏幕尺寸。LINES是屏幕上的行数,COLS是列数。右下角的位置是LINES-1,COLS-1。
例如,如果你想把光标移到第10行和第30列,你可以用这些坐标使用移动功能。
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
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列打印 "按任何键退出 "的文字。该程序使用getch()函数从键盘上获得一个字符,然后使用**endwin()**在程序完全退出前重置终端。
getch()是一个有用的函数,你可以用来做很多事情。我经常用它作为退出程序前暂停的一种方式。和大多数ncurses函数一样,getch()也有一个版本,叫做mvgetch(row, col),在等待一个字符之前移动到屏幕位置row,col。
用ncurses编译
如果你试图用通常的方法编译该示例程序,如gcc pause.c
,你可能会从链接器中得到一个巨大的错误列表。这是因为ncurses库没有被GNU C编译器自动链接。相反,你需要使用-l ncurses
命令行选项来加载它进行链接。
$ gcc -o pause pause.c -lncurses
运行新的程序将打印一个简单的 "按任何键退出 "的信息,该信息或多或少地集中在屏幕上。
图1:一个居中的 "按任何键退出 "的程序信息。
用ncurses建立更好的程序
探索ncurses库的功能,了解在屏幕上显示文本的其他方法。你可以在 man ncurses 手册页中找到所有ncurses函数的列表。它给出了ncurses的总体概述,并提供了一个类似表格的不同ncurses函数的列表,并提供了对有完整细节的手册页面的参考。例如,printw是在*curs_printw(3X)*手册页中描述的,你可以用:
$ man 3x curs_printw
或直接查看。
$ man curs_printw
使用ncurses,你可以创建更有趣的程序。通过在屏幕上的特定位置打印文本,你可以创建游戏和高级实用程序,在终端中运行。