快捷搜索:

UNIX 萤幕导向程式的发展利器

校园网路策进会

会长 林建宏

■ 媒介

信托您在网路上必然用过如 tin,elm 等对象, 这些软体有项合营的特色,

即他们能使用高低阁下等偏向键来节制游标的位置. 除此之外, 这些程式

的画面也较为美不雅. 对 ogramming 有喜欢的同伙必然对此认为好奇, 也

许他能在 PC 上用 Turbo C 随意马虎地写出类似的程式, 然而, 但当他将相同

的程式一字不变地移到事情站上来编译时, 却呈现一堆抓也抓不完的差错.

着实, 缘故原由很简单, 他应用的函式库可能在 UNIX 上是没有定义的. 有些

在 Turbo-C 上被广泛应用的一些函式, 可能在 UNIX 上是不被定义的.

为了因应网路上种种各样的终端机形态 (terminal), UNIX 上不凡成长出

一套函式库, 专门用来处置惩罚 UNIX 上游标移动及萤幕的显示. 这便是本篇

文章要为您先容的 - curses.h 函式库. 使用这个函式库, 您也可以写出

像 elm 般使用偏向键来移动光棒位置的程式. (CCCA 迩来所供给的线上选

课程式, 及程式办事界面, 等于笔者使用 curses 成长而成的 )

■ curses 的历史与版本

cureses 最早是由柏克莱大年夜学的 Bill Joy 及 Ken Arnold 所成长出来的.

当时成长此一函式库主要缘故原由是为了前进程式对不合终端机的相容性而设

计的. 是以, 使用 curses 成长出来的程式将和您所应用的终端机无关.

也便是说, 您不必担心您的程式由于换了一部终端机而无法应用. 这对程

式设计师而言, 尤其是网路上程式的撰写, 是件相称紧张的一件事.

curses之以是能对上百种以上的终端机事情, 是由于它将所有终端机的资

料, 寄放在一个叫 termcap 的资料库, ( 而在第二版的 System V 系统中

, 新版的 curses 以 terminfo 取代原本的 termcap). 有了这些记录, 程

式就能够知道碰着哪一种终端机时, 须送什麽字元才能移动游标的位置,

送什麽字元才能清除全部萤幕清除. (* 注一)

别的, 本文的先容 以 System V 的 curses 版本为主.

■ 若何在您的程式应用 curses ?

在您的 C 程式的档头将include 进来.当您引进 curses.h

这个函式库後, 系统会自动将和 一并 include 进

来.别的, 在 System V 版本中,这个函式库也将一并

include进来.

#include

main()

{

: :

: :

}

当然, 您的系统内必须放有 curses.h 这个函式库.

■ 若何编译(compile)

当您编辑好您的程式, 在 UNIX 提示符号下键入:

% /usr/5bin/cc [file.c] -lcurses

^^^^^^^

引进 curses.h 这个 library

或 % /usr/5bin/cc [file.c] -lcurses -ltermlib

(*注二)

■ 若何开始我的第一个 curses 程式?

在开始应用 curses 的统统敕令之前, 您必须先使用 initscr()这个函式

来开启 curses 模式.

相对的, 在停止 curses 模式前 ( 平日在您停止程式前 ) 也必须以

endwin()来关闭 curses 模式.

#include

main()

{

initscr();

: :

: :

: :

endwin();

}

这是一样平常 curses 程式标准的模式.

此外, 您可以就您程式所须, 而做不合的设定. 当然, 您可以不做设定,而

只是呼叫 initscr().

您可以自己写一个函式来寄放所有您所须要的设定. 寻常应用时, 只要呼

叫这个函式即可启动 curses 并完成统统设定.

下面的例子, 等于笔者将寻常较常用的一些设定放在一个叫 initial()的函

式内.

void initial()

{

initscr();

cbreak();

nonl();

noecho();

intrflush(stdscr,FALSE);

keypad(stdscr,TRUE);

refresh();

}

各函式分手先容如下:

□ initscr()

initscr() 是一样平常 curses 程式必须先呼叫的函数, 一但这个函数

被呼叫之後, 系统将根据终端机的形态并启动 curses 模式.

□ endwin()

curses 平日以呼叫 endwin() 来停止程式. endwin() 可用来关闭

curses 模式, 或是暂时的跳离 curses 模式.要是您在程式中须要

call shell ( 如呼叫 system() 函式 ) 或是必要做 system call,

就必须先以 endwin() 暂时跳离 curses 模式. 最後再以

wrefresh() doupdate() 来重返 curses 模式.

□ cbreak()

nocbreak()

当 cbreak 模式被开启後, 除了 DELETE 或 CTRL 等仍被视为不凡

节制字元外统统输入的字元将顿时被逐一读取.当处於 nocbreak 模

式时, 从键盘输入的字元将被储存在 buffer 里直到输入 RETURN

或 NEWLINE.在较旧版的 curses 须呼叫 crmode(),nocrmode() 来

取代 cbreak(),nocbreak()

□ nl()

nonl()

用来抉择当输入资料时, 按下 RETURN 键是否被对应为 NEWLINE 字

元 ( 如 \n ).

而输出资料时, NEWLINE 字元是否被对应为 RETURN 和 LINDFEED

系统预设是开启的.

□ echo()

noecho()

此函式用来节制从键盘输入字元时是否将字元显示在终端机上.系统

预设是开启的.

□ intrflush(win,bf)

呼叫 intrflush 时须传入两个值:

win 为一 WINDOW 型态指标, 平日传入标准输进出萤幕 stdscr

bf 为 TRUE 或 FALSE

当 bf 为 true 时, 当输入中断字元 ( 如 break) 时, 中断的反映

将较为快速.但可能会造成萤幕的错乱.

□ keypad(win,bf)

呼叫 keypad 时须传入两个值:

win 为一 WINDOW 型态指标, 平日传入标准输进出萤幕 stdscr

bf 为 TRUE 或 FALSE

当开启 keypad 後, 可以应用键盘上的一些不凡字元, 如高低阁下

等偏向键, curses 会将这些不凡字元转换成 curses.h 内定义的一

些不凡键. 这些定义的不凡键平日以 KEY_ 开首.

□ refresh()

refresh() 为 curses 最常呼叫的一个函式.

curses 为了使萤幕输进出达最佳化, 当您呼叫萤幕输出函式妄图改

变萤幕上的画面时, curses 并不会顿时对萤幕做改变, 而是等到

refresh() 呼叫後, 才将刚才所做的更改一次完成. 其馀的资料将

保持不变. 以尽可能送起码的字元至萤幕上. 削减萤幕重绘的光阴.

要是是 initscr() 後第一次呼叫 refresh(), curses 将做清除萤

幕的事情.

■ 游标的节制

move(y,x) 将游标移动至 x,y 的位置

getyx(win,y,x) 获得今朝游标的位置

(请重视! 是 y,x 而不是 &y,&x )

■ 有关清除萤幕的函式

clear()

erase() 将全部萤幕清除

(请重视共同refresh() 应用)

■ 若何在萤幕上显示字元

echochar(ch) 显示某个字元

addch(ch) 显示某个字元

mvaddch(y,x,ch) 在(x,y) 上显示某个字元

相称於呼叫 move(y,x);addch(ch);

addstr(str) 显示一串字串

mvaddstr(y,x,str) 在(x,y) 上显示一串字串

相称於呼叫 move(y,x);addstr(str);

printw(format,str) 类似 printf() , 以必然的款式输出至萤幕

mvprintw(y,x,format,str) 在(x,y) 位置上做 printw 的事情.

相称於呼叫 move(y,x);printw(format,str);

■ 若何从键盘上读取字元

getch() 从键盘读取一个字元 (重视! 传回的是整数值)

getstr() 从键盘读取一串字元

scanw(format,&arg1,&arg2...) 犹如 scanf, 从键盘读取一串字元

□例:

int ch;

char string1[80]; /* 请重视! 弗成宣告为 char *string1; */

char string2[80];

echo(); /* 开启 echo 模式, 使输入顿时显示在萤幕上 */

ch=getch();

string1=getstr();

scanw("%s",string2);

mvprintw(10,10,"String1=%s",string1);

mvprintw(11,10,"String2=%s",string2);

■ 若何使用偏向键

curses 将一些如偏向键等不凡节制字元, 以 KEY_ 为开首定义在 curses.h

这个档案里头, 如 KEY_UP 即代表偏向键的 " ↑ ". 但, 要是您想应用

curses.h 所为您定义的这些不凡键的话, 您就必须将 keypad 设定为

TRUE. 否则, 您就必须自己为所有的不凡键定义了.

curses.h 为一些不凡键的定义如下:

KEY_UP 0403 ↑

KEY_DOWN 0402 ↓

KEY_LEFT 0404 ←

KEY_RIGHT 0405 →

KEY_HOME 0406 Home key (upward+left arrow)

KEY_BACKSPACE 0407 backspace (unreliable)

KEY_F0 0410 Function keys.

KEY_F(n) (KEY_F0+(n)) Formula for f .

KEY_NPAGE 0522 Next page

KEY_PPAGE 0523 Previous page

以上仅列出笔者较常应用的一些节制键, 至於其他节制键的定义, 请自行参

阅 man curses (* 注三)

一并为您列出其他常用的一些不凡字元

[TAB] /t

[ENTER] /r

[ESC] 27

[BACKSPACE] 127

您可能还会对下面的文章感兴趣: