C/C++ ncurses 用法與範例教學

本篇 ShengYu 會介紹如何在 C/C++ 使用 ncurses library ,同時簡單介紹 ncurses 範例程式,以及怎麼編譯 ncurses 程式。

ncurses(new curses)是一個程式函式庫,它提供了API 讓程式設計師編寫獨立於終端的基於文字的使用者介面 (TUI,text-based user interfaces),例如:編譯 linux 的 make menuconfig。

curses 是一個建構於 termcap/terminfo 之上的通用程式庫。而 ncurses 是 curses 的衍生改良版本。以下就來介紹這強大的 ncurses library 吧!

安裝 ncurses library 套件

在 Debian/Ubuntu 的 Linux 系统下使用以下指令安装 ncurses,

1
sudo apt-get install libncurses5-dev

在 RHEL/CentOS/Fedora 的 Linux 系统下使用以下指令安装 ncurses,

1
sudo yum install ncurses-devel

這樣在編譯程式時,就可以引用 curses.h 標頭檔,連結時加上 -lncurses。

C/C++ ncurses 範例程式

C/C++ 在使用 ncurses 前要先引用 #include <curses.h> 標頭檔,
一開始用 initscr() 初始化 curses 視窗,並且有對應的 endwin() 關閉視窗,
接下來就是一些設定的 API,然後使用 mvprintw() 在中間位置輸出 Hello World 字串。

ncurses-1.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// gcc ncurses-1.c -o a.out -lncurses
#include <curses.h>
#include <string.h>

int main()
{
initscr();
raw();
noecho();
curs_set(0);

char *str = "Hello World";

mvprintw(LINES/2, (COLS-strlen(str))/2, str);
refresh();

getch();
endwin();
return 0;
}

程式執行結果如下圖所示,

下列範例是簡單的一個數學問題,並要求使用者輸入答案並回答對或錯,在這個例子中可以學習到基本的 ncurses 的程式所常用到的 API,
用 getstr() 取得使用者鍵盤輸入的字串,然後再判斷輸入的字串是不是正確的答案,

ncurses-2.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// gcc ncurses-2.c -o a.out -lncurses
#include <curses.h>
#include <string.h>

int main()
{
char str[80];

initscr();
cbreak();
echo();

mvprintw(10, 10, "2+3=%s", str);

getstr(str);

if (strcmp("5", str) == 0)
mvprintw(11, 10, "Correct\n");
else
mvprintw(11, 10, "Wrong\n");

mvprintw(12, 10, "press any key to quit...");
getch();
endwin();
return 0;
}

程式執行結果如下圖所示,

如何編譯

確認在 Makefile 裡的連結 LDFLAGS 加上 -lncurses 然後輸入以下指令進行編譯,

1
make

或直接使用 gcc 指令

1
gcc main.c -o a.out -lncurses

ncurses API 說明

以下說明一些常用的 ncurses API
initscr():初始化 curses 視窗。
所有使用 ncurses 的程式,一開始都要 initscr。這會設定 ncurses 函式庫的初始狀態,並且把程式執行之前的螢幕存起來。
endwin():關閉視窗。
所有使用 ncurses 的程式,結束時都要 endwin。這會讓 ncurses 函式庫做還原恢復的動作,例如把螢幕恢復成程式執行之前的狀態。
cbreak()
當 cbreak 模式被開啟後,除了 DELETE 或 CTRL 等仍被視為特殊控制字元外一切輸入的字元將立刻被一一讀取.當處於 nocbreak 模式時,從鍵盤輸入的字元將被儲存在 buffer 裡直到輸入 RETURN 或 NEWLINE。在較舊版的 curses 須呼叫 crmode(),nocrmode() 來取代 cbreak(),nocbreak()。
echo():用來控制從鍵盤輸入字元時是否將字元顯示在終端機上。預設是開啟的。
noecho():關閉輸入字元的顯示,鍵盤輸入的字元將不被顯示。
curs_set(0):關閉 cursor。
refresh():更新螢幕。
為了提高執行效率,ncurses 中的大部分副程式所製造的效果,都不是馬上會顯現出來的,而是等到程式設計師呼叫 refresh 時才把先前所有指定的效果一次顯現出來。但是輸出入選項設定不在此限,見 curs_inopts(3) 與 curs_outopts(3)。
clear():清除螢幕。
注意螢幕並非馬上清除,而是等呼叫 refresh 之後才清除。
mvprintw(y,x,format,str):在(x,y)位置輸出字串。
在(x,y) 位置上做 printw 的工作.相當於呼叫 move(y,x);printw(format,str);。
getstr():從鍵盤讀取一串字元。
getch():從鍵盤讀取一個字元。
raw():阻止字元緩衝,令程式即時處理鍵盤輸入,一些終端命令(中斷[Ctrl-c],掛起[Ctrl-z])也會被交給程式處理。

以上就是 C/C++ ncurses 用法與範例教學,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它參考
UNIX 螢幕導向程式的發展利器 - curses
http://www2.csie.ntnu.edu.tw/~ghhwang/course_slices/OS/Curses_Usage.txt

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ fopen 用法與範例
C/C++ fread 用法與範例
C/C++ fgets 用法與範例
C/C++ fputs 用法與範例
C/C++ fclose 用法與範例