如何在Windows上使用Perl从STDIN中读取单个字符?

Mik*_*kes 6 windows perl

使用Perl,如何在STDIN不需要用户输入Enter的情况下捕获单个字符(类似于C的getch()功能)?

Perl有一个getc()函数,但是根据perlfunc:

但是,它无法单独用于获取单个字符而无需等待用户按Enter键.

perlfunc文档确实提供了一种使用单个字符读取的方法,getc()但它需要使用操作终端设置stty.我正在编写的脚本需要在Windows上运行(没有cygwin,msys等) - 所以这不是一个选项.

bri*_*foy 13

perlfaq5的回答我怎样才能从文件中读取单个字符?从键盘?


您可以对大多数文件句柄使用内置的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() }
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

  • @gameover:`ppm search Term :: ReadKey`表示它是. (3认同)
  • 这应该告诉你是否安装了它(我在ActiveState 5.10.1上有它):perl -MTerm :: ReadKey -e 1 (2认同)

Jon*_*erg 10

你想要这个模块:Term :: ReadKey.