使用Perl,如何从STDIN
捕获单个字符而无需用户点击输入(类似于C的getch()
功能)?
Perl有一个getc()
函数,但根据perlfunc:
但是,它本身不能用于获取 单个字符无需等待 用户按Enter键。
perlfunc docs do 提供了一种使用getc()
读取单个字符的方法,但它需要使用stty
来操作终端设置。我写的脚本需要在Windows上工作(没有cygwin,msys等) - 所以这不是一个选项。
答案 0 :(得分:13)
从perlfaq5回答How can I read a single character from a file? From the keyboard?
您可以对大多数文件句柄使用内置getc()函数,但它不会(轻松)在终端设备上运行。对于STDIN,要么使用CPAN中的Term::ReadKey模块,要么使用percunc中getc中的示例代码。
如果您的系统支持便携式操作系统编程接口(POSIX),您可以使用以下代码,您将注意到该代码也会关闭回显处理。
#!/usr/bin/perl -w
use strict;
$| = 1;
for (1..4) {
my $got;
print "gimme: ";
$got = getone();
print "--> $got\n";
}
exit;
BEGIN {
use POSIX qw(:termios_h);
my ($term, $oterm, $echo, $noecho, $fd_stdin);
$fd_stdin = fileno(STDIN);
$term = POSIX::Termios->new();
$term->getattr($fd_stdin);
$oterm = $term->getlflag();
$echo = ECHO | ECHOK | ICANON;
$noecho = $oterm & ~$echo;
sub cbreak {
$term->setlflag($noecho);
$term->setcc(VTIME, 1);
$term->setattr($fd_stdin, TCSANOW);
}
sub cooked {
$term->setlflag($oterm);
$term->setcc(VTIME, 0);
$term->setattr($fd_stdin, TCSANOW);
}
sub getone {
my $key = '';
cbreak();
sysread(STDIN, $key, 1);
cooked();
return $key;
}
}
END { cooked() }
CPAN的Term :: ReadKey模块可能更容易使用。最新版本还包括对非便携式系统的支持。
use Term::ReadKey;
open(TTY, "</dev/tty");
print "Gimme a char: ";
ReadMode "raw";
$key = ReadKey 0, *TTY;
ReadMode "normal";
printf "\nYou said %s, char number %03d\n",
$key, ord $key;
答案 1 :(得分:10)
您需要此模块:Term::ReadKey。