使用 ncurses 在 Linux 上定位屏幕上的文本

在 Linux 中使用 ncurses 将文本放置在屏幕上的特定位置,并启用更友好的用户界面。
52 位读者喜欢这篇文章。
Person using a laptop

大多数 Linux 实用程序只是从屏幕底部滚动文本。但是,如果你想将文本放置在屏幕上,例如用于游戏或数据展示,该怎么办? 这就是 ncurses 发挥作用的地方。

curses 是一个古老的 Unix 库,支持文本终端屏幕上的光标控制。 名称curses来自术语光标控制。 几年后,其他人编写了一个改进版本的 curses 以添加新功能,称为new cursesncurses。 你可以在每个现代 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”消息,该消息或多或少地位于屏幕的中心

centered message in a program window

图 1:程序中居中的“press any key to quit”消息。

使用 ncurses 构建更好的程序

浏览 ncurses 库函数以了解其他向屏幕显示文本的方式。 你可以在 man ncurses 手册页中找到所有 ncurses 函数的列表。 这提供了 ncurses 的一般概述,并提供了一个类似表格的 ncurses 函数列表,并引用了包含完整细节的手册页。 例如,printwcurs_printw(3X) 手册页中进行了描述,你可以使用以下命令查看该手册页

$ man 3x curs_printw

或者只是

$ man curs_printw

使用 ncurses,你可以创建更有趣的程序。 通过在屏幕上的特定位置打印文本,你可以创建游戏和高级实用程序以在终端中运行。

接下来阅读什么
标签
photo of Jim Hall
Jim Hall 是一位开源软件倡导者和开发者,以 GNOME 中的可用性测试以及 FreeDOS 的创始人和项目协调员而闻名。

评论已关闭。

Creative Commons License本作品根据知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.