当前位置:  技术问答>linux和unix

谁可以告诉我那有讲ncurses的?越具体越好!

    来源: 互联网  发布时间:2014-10-22

    本文导语:  |寄信人: guest.bbs@hgluo.hust.edu.cn  标  题: ◇ UNIX 萤幕导向程式的发展利器 - curses (一)  发信站: 华南理工大学 BBS木棉站  日  期: Thu Feb 20 14:15:37 1997                        UNIX 萤幕导向程式的发展利器...


|
寄信人: guest.bbs@hgluo.hust.edu.cn  标  题: ◇ UNIX 萤幕导向程式的发展利器 - curses (一)  发信站: 华南理工大学 BBS木棉站  日  期: Thu Feb 20 14:15:37 1997                        UNIX 萤幕导向程式的发展利器 - curses                                                              校园网路策进会                                                           会长    林建宏         ■ 前言         相信您在网路上一定用过如  tin,elm 等工具, 这些软体有项共同的特色,      即他们能利用上下左右等方向键来控制游标的位置.  除此之外, 这些程式      的画面也较为美观. 对 Programming 有兴趣的朋友一定对此感到好奇, 也      许他能在 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          ■ 如何改变萤幕显示字元的属性         为了使输出的萤幕画面更为生动美丽,  我们常须要在萤幕上做一些如反白,      闪烁等变化.  curses 定义了一些特殊的属性, 透过这些定义, 我们也可以      在 curses 程式□控制萤幕的输出变化.          attron(mod)    开启属性       attroff(mod)   关闭属性         curses.h 里头定义了一些属性, 如:          A_UNDERLINE    加底线       A_REVERSE      反白       A_BLINK        闪烁       A_BOLD         高亮度       A_NORMAL       标准模式 (只能配合 attrset() 使用)            当使用 attron() 开启某一种特殊属性模式後, 接下来在萤幕的输出都会以      该种属性出现. 直到您呼叫 attroff() 将此模式关闭.         请注意, 当您欲 attron() 开启另一种属性时, 请记得利用 attroff()先关      闭原来的属性, 或直接以 attrset(A_NORMAL)  将所有特殊属性关闭.否则,      curses 会将两种属性做重叠处理.          □例:             attrset(A_NORMAL);            /* 先将属性设定为正常模式       */          attron(A_UNDERLINE);          /* 加底线                       */          mvaddstr(9,10,"加底线");      /* 加底线输出一串字元           */          attroff(A_UNDERLINE);         /* 关闭加底线模式, 恢复正常模式 */          attron(A_REVERSE);            /* 开启反白模式                 */          mvaddstr(10,10,"反白");       /* 输出一串反白字元             */          attroff(A_REVERSE);           /* 关闭反白模式, 恢复正常模式   */          attron(A_BLINK);              /* 开 羯了改J?                */          mvaddstr(11,10,"闪烁");       /* 输出一  烁字元             */          attroff(A_BLINK);             /* 关闭闪烁模式, 恢复正常模式   */          attron(A_BOLD);               /* 开启高亮度模式               */          mvaddstr(12,10,"高亮度");     /* 输出一串高亮度字元           */          attroff(A_BOLD);              /* 关闭高亮度模式, 恢复正常模式 */          ■ 其他常用的一些函式            beep()              发出一声哔声         box(win,ch1,ch2)    自动画方框  ch1: 画方框时垂直方向所用字元                                         ch2: 画方框时水平方向所用字元                                            example: box(stdscr,'|','-');                                         将以 | 及 - 围成一个方框       ■ 应用完整□例         下面所举的例子,  即完全利用刚刚所介绍的含式来完成.这个程式可将从键      盘上读取的字元显示在萤幕上, 并且可以上下左右方向键来控制游标的位置      , 当按下 [ESC] 後, 程式即结束.         您有没有发现, 这不就是一个简单全萤幕编辑器的雏形吗?           #include                   /* 引进 curses.h , 并自动引进 stdio.h */           #define StartX  1                    /* 决定游标初始位置 */     #define StartY  1        void initial();        main()     {        int x=StartX;                     /* 宣告 x,y 并设定其初值              */           int y=StartY;        int ch;                           /* 宣告 ch 为整数,配合 getch() 使用   */              initial();                        /* 呼叫 initial(), 启动 curses 模式,  */                                             /* 并完成其它设定                     */              box(stdscr,'|','-');              /* 画方框                             */              attron(A_REVERSE);                /* 开启反白模式                       */           mvaddstr(0,20,"Curses Program");  /* 在 (20,0) 处输出反白字元           */           attroff(A_REVERSE);               /* 关闭反白模式                       */              move(x,y);                        /* 将游标移至初始位置                 */              do {                              /* 以无限回圈不断等待输入             */            ch=getch();                      /* 等待自键盘输入字元         switch(ch) {                     /* 判断输入字元为何                   */                  case KEY_UP: --y;             /* 判断是否"↑"键被按下               */                            break;            case KEY_DOWN: ++y;           /* 判断是否"↓"键被按下               */                            break;            case KEY_RIGHT: ++x;          /* 判断是否"→"键被按下               */                            break;            case KEY_LEFT: --x;           /* 判断是否"←"键被按下               */                            break;            case 'r':                    /* 判断是否 ENTER 键被按下            */                         ++y;                      x=0;                      break;            case 't':                    /* 判断是否 TAB 键被按下              */                         x+=7;                      break;            case 127:                     /* 判断是否 BACKSPACE 键被按下        */                          mvaddch(y,--x,' ');/* delete 一个字元                    */                          break;               case 27: endwin();            /* 判断是否[ESC]键被按下              */                        exit(1);             /* 结束 curses 模式                   */                                             /* 结束此程式                         */                  default:                     addch(ch);           /* 如果不是特殊字元, 将此字元印出     */                        x++;                     break;          }          move(y,x);                      /* 移动游标至现在位置                 */           } while (1);      }        void initial()                       /* 自定开启 curses 函式               */        {         initscr();         cbreak();         nonl();         noecho();         intrflush(stdscr,FALSE);         keypad(stdscr,TRUE);         refresh();      }             ■ 後记         学完了上述的一些命令,  相不相信您已经可以写出一个漂亮的全萤幕编辑      器了? 事实上, curses 提供的函式不下  200 个, 可是笔者认为, 一切再      复杂的函式都可以用本文提到的一些组合变化而成,  学了太多的函式, 只      是徒增自己困扰罢了.  当然,  如果您对其它函式有兴趣,  可以自行参阅      curses 说明档.  ( 方法: % man curses ) 本文不过行抛砖引玉之效, 也      希望未来能陆续出现更多同学自行创作的程式.          * 任何疑问及建议, 欢迎 e-mail 至 ljh@CCCA.NCTU.edu.tw. 谢谢 ! *            注一:       请参考 /usr/share/lib/termcup              /usr/share/lib/terminfo/s/sun      注二:       1.如果是 BSD 的版本, 需使用         cc [file.c] -lcurses -ltermcap 来完成 compile.       2.计中工作站不知何故将原来的 /usr/5bin/cc 更改为 /usr/5bin/cc.org         因此, 您若想在计中工作站 compile curses 程式.需以 /usr/5bin/cc.org         取代 /usr/5bin/cc , 否则 compile 可能发生错误.       3.较旧版的 curses 需同时引进 curses 和 termlib 这两个 library,         因此, 您必须使用 /usr/5bin/cc [file.c] -lcurses -ltermlib 来 compile.      注三:        根据笔者的经验, 上下左右方向键应可正常使用而不会发生问题, 但其它        如 PgUp,PgDn,功能键,Home,End 等特殊键, 很容易因机器, 键盘不同而无        法使用, 因此, 若您的程式须要在不同的机器上使用, 建议您只用方向键来        控制, 其它的特殊键少用为妙.        至於 PgUp,PgDn 一些特殊键的控制方法, 由於较为复杂, 有兴趣的同学可参        考 tin 原始程式 curses.c 内所使用的一些方法. 

    
 
 

您可能感兴趣的文章:

  • 我从网上下载LUNUX然后用盘刻录了可以安装吗?如果可以请告诉我下载地址可以吗?谢谢,我学习用的!谢谢
  • 各位,能否告诉小弟那里有《thinking in java》可以下载啊!thx
  • 有谁可以告诉我..在UNIX下可以用什么数据库啊 ...
  • 高分求助 。。。。。。。。。。。。各位高手。可以不可以告诉我。当我下载完resin之后应该如何配置好一个jsp的环境。我的操作系统是win2k professional
  • 谁可以告诉我“classpath”里边那个“.”是什么意思?
  • 急,急,谁能告诉我jcsp教材SL-275在那里可以下载,万分感谢!!
  • 那位哥哥能告诉我那里可以下minix源码?
  • 是可以告诉我如何修改lilo的设置,刚装linux red hat 7.1
  • 谁能告诉我几个linux的新闻组地址,e文中文都有可以
  • vmware有在win98下用的吗?帮忙告诉一个可以下的下载地址。
  • 寻求EditPlus2.11的注册码?或者告诉我可以到哪里去找?
  • 谁可以告诉我JBuilder4的注册码?
  • 谁可以告诉我TextPad的注册码?
  • 哪位仁兄可以告诉我在linux下如何访问本机windows下的文件?
  • 求助:各位大侠,麻烦你们能不能告诉我有没有一种软件可以让和相互操作各自的分区?
  • 谁能推荐一个linux下的mysql的图形化操作工具?类似于mysql-front之类!!!并告诉我在哪儿可以下载??
  • com.borland.dbswing.* 在什么文件里啊?可以发给我一个吗?Rex_fa@163.com 告诉我也行
  • 不知谁可以告诉我,scjp认证的有关问题?
  • 编译出现以下错误,有谁可以告诉我是什么问题吗?
  • 我现在想学习dos 6.22 但不知道从哪儿可以找到dos的所有命令,不然这没法学了,如果有谁知道的,请告诉我。谢谢!!
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • C++ MultiMaps 成员 max_size():返回可以容纳的最大元素个数
  • tc下可以,gcc下不可以.请告说我,怎样就都可以了
  • 那位哥哥能告诉我那里可以下minix源码? iis7站长之家
  • 生产者消费者问题为什么不可以共用一个信号量,如果这个信号量可以设置取值固定为0到N,即当信号量取值为N的时候阻塞进程,是否也可以?
  • C++ Maps 成员 max_size():返回可以容纳的最大元素个数
  • weblogic可不可以当作jndi服务器使用?如果可以,请问如何管理?
  • 网站英文/中文域名字符集即网站英文/中文域名可以包含哪些字符
  • 请问用ftp可以不可以把整个目录一起上传。
  • 必看!程序员升级之路,看了可以少走很多弯路
  • linux可不可以和windows共享??可以的话,该怎么做?
  • 怎样写一个shell,可以查看一个文件的内容,并且有翻页的内容,并可以打印的
  • 可以从硬盘上安装redhat吗?linux可以用ghost备份吗?
  • 学习unix,急需教程,请问哪里可以下载,或者谁可以提供这方面的材料!
  • 在线等,为什么我的代码原来可以运行,现在不可以了????TextPad
  • 为什么在网页中有的applet可以显示,有的不可以显示 在线等待!!!!!
  • 有什么可以在2k server下可以用的分区工具?
  • iconv可以用来转换文字编码,有没有可以用来识别编码的?
  • 为什么我在linux7.1中有些命令有时可以用有时不可以用?
  • 怎样让一个.SH文件在任何目录下都可以直接敲入文件名*.SH就可以运行?
  • 我发现在Redhat Linux中有个选项可以连上MSN,不知怎么才可以连上,谢谢
  • linux如何创建一个共享内存 可以mount 可以创建目录之类 跟硬盘分区一样


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3