從Hello World 程序開始
歡迎來到ncurses 的世界。在我們踏上學習ncurses 的路途之前,讓我們先寫一個小程序,來了解一下應用ncurses 庫所編寫程序的結構。
編譯包含NCURSES 庫函數的程序
如果要調用ncurses 庫中的函數,你必須在代碼中加載ncurses.h 文件,就是要在C 或C++
程序開頭添加“#include <ncurses.h>”,然后在鏈接時標記-lncurses參數。如果ncurses 庫不存在,可以按以下方法安裝:
sudo apt-get install libncurses5-dev
例1:Hello World !!!程序
#include <ncurses.h>
int main()
{
initscr(); /* 初始化,進入NCURSES 模式*/
printw("Hello world!!!"); /* 在虛擬屏幕上打印Hello, World!!! */
refresh();/* 將虛擬屏幕上的內容寫到顯示器上,并刷新*/
getch();/* 等待用戶輸入*/
endwin();/* 退出NCURSES 模式*/
return 0;
}
編譯:gcc -o helloword helloword.c -lncurses
運行:./helloword
示例剖析
這個程序在顯示器屏幕上打印“Hello World !!!”后等待用戶按任意鍵退出。這個小程序展示了如何初始化并進入curses 模式、處理屏幕和退出curses 模式。讓我們逐行的分析這個小程序:
關于initscr() 函數
initscr()函數將終端屏幕初始化為curses 模式。它用來清除屏幕上所有的字符,并等待下一部處理。所以在調用其它的curses 函數前,要先調用initscr()函數初始化屏幕。這個函數初始化了curses 系統并且為當前屏幕(也就是“stdscr”)和相關的數據結構分配內存。
在以前的計算機上曾經出現過一個極端的例子:因為系統中的可用內存太小,以至于initscr()函數無法分配足夠的內存給相關的數據結構,從而導致curses 系統初始化失敗。在以后的章節中我們將介紹如何定制屏幕的初始化模式。
神秘的refresh() 函數
第二行的printw()函數用于把字符串“Hello,World!!!”輸出到虛擬的屏幕上。這個函數在用法上和printf()函數很像。不同的是:printw()函數把字符串輸出到“stdscr”的虛擬窗口坐標(0,0)上(從顯示的結果來看,坐標(0,0)在屏幕的左上角上)。
現在該說說這個神秘的refresh()函數了。在我們使用printw 函數打印“Hello World!!!”時,實際上這個消息打印到了一個叫作“stdscr”的虛擬窗口上,沒有被直接輸出到屏幕上。printw()函數的作用是不斷將一些顯示標記和相關的數據結構寫在虛擬顯示器上,并將這些數據寫入stdscr 的緩沖區內。為了顯示這些緩沖區中的數據我們必須使用refresh()函數告訴curses系統將緩沖區的內容輸出到屏幕上。
通過這種機制程序員能夠不斷在虛擬屏幕上寫數據。然后調用refresh()函數讓輸出的操作看起來是一次完成的。因為refresh()函數只核查窗口和數據中變動的部分,這種富有彈性的設計提供了一個高效的反饋機制。但是這有時很打擊初學者的積極性。因為對于初學者來說忘記在輸出后調用refresh()函數是很惱人的錯誤。不過不用擔心,很多人都會犯這樣的錯誤。
關于endwin()函數
后,別忘了退出curses 模式。否則,在程序結束后你的終端可能會運轉得不正常。endwin()函數釋放了curses 子系統和相關數據結構占用的內存,使你能夠正常返回控制臺模式。這個函數必須是在你完成所有的curses 操作以后才可以調用。(譯者注:如果你在endwin()函數后再調用其它的curses 的函數。很顯然,那些語句不會執行。)說到這里,順便提醒一下。如果你的程序不能正常地顯示東西了。請務必看看initscr()函數和endwin()函數是不是在不該被調用的地方調用了。