2. 你好,世界 !!!

欢迎来到 curses 的世界。在我们深入研究库并了解其各种功能之前,让我们编写一个简单的程序,向世界问好。

2.1. 使用 NCURSES 库编译

要使用 ncurses 库函数,您必须在程序中包含 ncurses.h。要将程序与 ncurses 链接,应添加标志 -lncurses。

    #include <ncurses.h>
    .
    .
    .

    compile and link: gcc <program file> -lncurses

示例 1. 你好,世界 !!! 程序

#include <ncurses.h>

int main()
{	
	initscr();			/* Start curses mode 		  */
	printw("Hello World !!!");	/* Print Hello World		  */
	refresh();			/* Print it on to the real screen */
	getch();			/* Wait for user input */
	endwin();			/* End curses mode		  */

	return 0;
}

2.2. 解剖

上面的程序将 “你好,世界 !!!” 打印到屏幕并退出。该程序演示了如何初始化 curses、进行屏幕操作以及结束 curses 模式。让我们逐行解剖它。

2.2.1. 关于 initscr()

函数 initscr() 在 curses 模式下初始化终端。在某些实现中,它会清除屏幕并呈现空白屏幕。要使用 curses 包进行任何屏幕操作,必须首先调用此函数。此函数初始化 curses 系统并为我们当前的窗口(称为stdscr)和一些其他数据结构。在极端情况下,此函数可能会因内存不足而无法为 curses 库的数据结构分配内存。

完成此操作后,我们可以进行各种初始化以自定义 curses 设置。这些细节将在 稍后 解释。

2.2.2. 神秘的 refresh()

下一行 printw 将字符串 “你好,世界 !!!” 打印到屏幕上。此函数在所有方面都类似于普通的 printf,除了它将数据打印到名为 stdscr 的窗口中的当前 (y,x) 坐标处。由于我们当前的坐标是 0,0,因此字符串打印在窗口的左上角。

这就引出了神秘的 refresh()。好吧,当我们调用 printw 时,数据实际上被写入到一个假想的窗口,该窗口尚未在屏幕上更新。printw 的工作是更新一些标志和数据结构,并将数据写入与 stdscr 对应的缓冲区。为了在屏幕上显示它,我们需要调用 refresh() 并告诉 curses 系统将内容转储到屏幕上。

这一切背后的理念是允许程序员在假想的屏幕或窗口上进行多次更新,并在完成所有屏幕更新后刷新一次。refresh() 检查窗口并仅更新已更改的部分。这提高了性能并提供了更大的灵活性。但是,这有时会让初学者感到沮丧。初学者常犯的一个错误是在通过 printw() 类函数进行一些更新后忘记调用 refresh()。我有时仍然忘记添加它 :-)

2.2.3. 关于 endwin()

最后,不要忘记结束 curses 模式。否则,程序退出后您的终端可能会表现异常。endwin() 释放 curses 子系统及其数据结构占用的内存,并将终端置于正常模式。在您完成 curses 模式后,必须调用此函数。