6.4 键盘
curses函数库不仅提供了控制屏幕显示的易用接口,还提供了控制键盘的简单方法。
6.4.1 键盘模式
键盘读取例程由键盘模式控制。用于设置键盘模式的函数有:
两个echo函数用于开启或关闭输入字符的回显功能。其余4个函数调用用于控制在终端上输入的字符传送给curses程序的方式。
为解释清楚cbreak函数的作用,你需要首先理解何为默认输入模式。当curses程序通过调用initscr函数开始运行时,输入模式被设置为预处理模式(或称为cooked模式)。这意味着所有处理都是基于行的,也就是说,只有在用户按下回车键之后,输入的数据才会被传送给程序。在这种模式下,键盘特殊字符被启用,所以按下合适的组合键即可在程序中产生一个信号,如果是通过串行口或调制解调器等连接终端,则流控也处于启用状态。程序可通过调用cbreak函数将输入模式设置为cbreak模式,在这种模式下,字符一经键入就被立刻传递给程序,而不像在cooked模式中那样首先缓存字符,直到用户按下回车键后才将用户输入的字符传递给程序。cbreak模式与cooked模式一样,键盘特殊字符也被启用,但一些简单的特殊字符,如退格键Backspace会被直接传递给程序处理,所以如果想让退格键保留原来的功能,你就必须自己在程序中实现它。
raw函数调用的作用是关闭特殊字符的处理,所以执行该函数调用后,再想通过输入特殊字符序列来产生信号或进行流控就不可能了。nocbreak函数调用将输入模式重新设置为cooked模式,但特殊字符的处理方式保持不变。noraw函数调用同时恢复cooked模式和特殊字符处理功能。
6.4.2 键盘输入
读取键盘输入非常简单,主要的函数有:
这些函数的行为与它们的非curses版本getchar、gets和scanf非常相似。要注意的是,getstr函数对其返回的字符串的长度没有限制,所以使用这个函数时要非常小心。如果所使用的curses版本支持getnstr函数(它可以对读取的字符数目加以限制),你就应该尽可能地用它来替代getstr函数。这与你在第3章中看到的gets和fgets函数非常类似。
下面是一个短小的示例程序ipmode.c,它演示了如何处理键盘。
实 验 键盘模式和输入
(1)首先,设置程序并执行初始化curses函数库的调用:
(2)用户输入密码时,你不能让密码回显在屏幕上。然后,检查用户输入的密码是否等于xyzzy:
(3)最后,重新启用键盘回显,并给出密码验证成功或失败的信息:
实验解析
关闭键盘输入回显并将输入模式设置为cbreak后,你设置一块内存区域用于接收用户输入的密码。每个输入的密码字符被立即处理并在屏幕的下一个位置上显示一个号。你需要在每次输出号后刷新屏幕,然后,用strncmp函数来比较用户输入的密码和保存在程序中的正确密码。
如果使用的curses函数库版本很老,你可能需要在getstr函数调用之前加上一个refresh函数调用。在ncurses版本中,getstr函数调用会自动刷新屏幕。