Термин Perl:: ReadKey не ожидают новой строки

В сценарии жемчуга я пытаюсь принять вход, не блокируясь, и не повторяя вводимые символы (Сценарий производит вывод, и я хочу иметь 'горячие клавиши' для изменения его поведения).

Я добрался до использования

use Term::ReadKey;
ReadMode( "cbreak", STDIN );
if($input = ReadKey($pause_time, STDIN)){
    #process input
}

Но после того как пользователь вводит что-либо затем остановки сценария, пока новая строка не вводится. Я хотел бы, чтобы вход был обработан на символ, не ожидая новой строки.

7
задан tim 16 June 2010 в 15:30
поделиться

2 ответа

Вот небольшая программа, которая делает то, что, как я думаю, вы хотите:

#!/usr/bin/perl

use strict;
use warnings;

use Term::ReadKey;

ReadMode 4;
END { ReadMode 0 }

print <<EOS;
q to quit
b to print in binary
o to print in octal
d to print in decimal
x to print in hexadecimal
EOS

my $control = "d";
my $i       = 0;
while (1) {
    #use "if" if you want to have a buffer of commands
    #that will be processed one per second  
    while (defined (my $key = ReadKey(-1))) {
        exit 0          if $key eq 'q';
        $control = $key if $key =~ /^[bodx]$/;
    }
    printf "%$control\n", $i++;
    sleep 1;
}
7
ответ дан 7 December 2019 в 03:11
поделиться

Я собирался оставить это как комментарий к вашему собственному «ответу», но решил, что мне нужно больше места.

cbreak эквивалентен необработанному режиму, за исключением того, что cbreak не перехватывает управляющие последовательности, такие как ctrl-c, ctrl-z и т. Д. Они оба собирают символы по одному. Разница в поведении между двумя режимами не является источником вашей проблемы. Если решение Часа делает что-то похожее на то, что вы планировали, то проблема, скорее всего, связана с тем, что вы отредактировали в строке #process input . Я уже отмечал, что ваш исходный сценарий работает нормально, если я заполню его чем-то элементарным, чтобы я мог видеть, что он работает. Например, небольшая поправка:

use strict;
use warnings;
use Term::ReadKey;

my ($char, $input, $pause_time);
ReadMode("cbreak");

# Collect all characters typed into $input
# and quit when '#' is typed.

$input = '';
while ($char = ReadKey($pause_time)) {
    last if $char eq '#';
    $input .= $char;
}

print "$input\n";

Мне не нужно нажимать «Enter» в конце этого, и это ничего не даст (кроме возврата каретки в $ input и запутывая веревку).

2
ответ дан 7 December 2019 в 03:11
поделиться
Другие вопросы по тегам:

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