Как я читаю отдельный символ из STDIN использование Perl в Windows?

Используя Perl, как я получаю отдельный символ от STDIN не нуждаясь в пользователе для удара входят (подобный C getch() функция)?

Perl имеет a getc() функция, но согласно perlfunc:

Однако это не может использоваться отдельно для выборки отдельных символов, не ожидая пользователя для удара, входят.

perlfunc документы делают позволяет читать односимвольное использование getc() но это требует управления терминальным использованием настроек stty. Сценарий, который я пишу потребностям работать над Windows (без cygwin, msys, и т.д.) - таким образом, это не опция.

6
задан brian d foy 7 January 2010 в 15:46
поделиться

2 ответа

Вам нужен этот модуль: Term::ReadKey.

10
ответ дан 8 December 2019 в 05:21
поделиться

Из ответа perlfaq5 в Как я могу прочитать один символ из файла? С клавиатуры?


Вы можете использовать встроенную функцию getc() для большинства файловых дескрипторов, но она не будет (легко) работать на терминальном устройстве. Для STDIN используйте либо модуль Term::ReadKey из CPAN, либо пример кода в getc в perlfunc.

Если ваша система поддерживает интерфейс программирования портативной операционной системы (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() }

Модуль Term::ReadKey из CPAN может быть более прост в использовании. Последние версии также включают в себя поддержку неподвижных систем.

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;
13
ответ дан 8 December 2019 в 05:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: