Perl术语::带箭头键的ReadKey

Perl术语::带箭头键的ReadKey,perl,console.readkey,readkey,Perl,Console.readkey,Readkey,我在ReadMode('cbreak')中使用Term::ReadKey读取单个字符,并根据输入执行操作。这适用于除箭头键以外的所有其他键。当按下箭头键时,该动作会执行3次,我理解这是因为箭头键会转换为“^[[A]”等 如何将箭头键转换为ReadKey可以解释的任意单个值 我尝试了以下代码,但不起作用: use Term::ReadKey; ReadMode('cbreak'); my $keystroke = ''; while ($keystroke ne 'h') { pr

我在ReadMode('cbreak')中使用Term::ReadKey读取单个字符,并根据输入执行操作。这适用于除箭头键以外的所有其他键。当按下箭头键时,该动作会执行3次,我理解这是因为箭头键会转换为“^[[A]”等

如何将箭头键转换为ReadKey可以解释的任意单个值

我尝试了以下代码,但不起作用:

use Term::ReadKey;

ReadMode('cbreak');

my $keystroke = '';

while ($keystroke ne 'h') {

    print "Enter key: "; 

    #Read user keystroke 
    $keystroke = ReadKey(0);

    chomp($keystroke);


    if(ord($keystroke) == 27) {
         $keystroke = ('0');
    }
}
以下是我根据建议编写的代码:

use Term::RawInput;
use strict;
use warnings;

my $keystroke = '';
my $special = ''; 

while(lc($keystroke) ne 'i' && lc($keystroke) ne 't'){

    my $promptp = "Enter key: ";

    ($keystroke,$special) = rawInput($promptp, 1);

    if ($keystroke ne '') {
        print "You hit the normal '$keystroke' key\n";
    } else {
        print "You hit the special '$special' key\n";
    }

    chomp($keystroke);

    $keystroke = lc($keystroke);
}

if($keystroke eq 'i') {
    #Do something
}

if($keystroke eq 't') {
    #Do something
}
现在,不管我按什么,我都不能退出这个循环

以下是输出:

Enter key: 
Enter key:
Enter key: You hit the normal 't' key

#Proceeds to function
虽然没有涵盖所有内容,但这是一个很好的开始:

use Term::RawInput;
my ($keystroke,$special) = rawInput("", 1);
if ($keystroke ne '') {
    print "You hit the normal '$keystroke' key\n";
} else {
    print "You hit the special '$special' key\n";
}

如果你想阅读“按键”的高级语义概念,而不是“来自终端的字节”的低级语义概念,那么你需要一些能够为你解析和收集这些多字节序列的东西

对于这类任务,我写道:


这是我的工作解决方案

use Term::ReadKey;

ReadMode('cbreak');

{
    #Temporarily turn off warnings so no messages appear for uninitialized $keystroke
    #that for some reason appears for the if statement
    no warnings;

    my $keystroke = '';

    while ($keystroke ne 'h') {

        print "\nEnter key: ";

        #Read user keystroke 
        $keystroke = ReadKey(0);

        #The first character for the arrow keys (ex. '^[[A') evaluates to 27 so I check for 
        #that
        if(ord($keystroke) == 27) {
            #Flush the rest of the characters from input buffer
            #This produces an 'Use of uninitialized value...' error
            #for the other two characters, hence 'no warnings' at the beginning.
            #This will ignore the other 2 characters and only cause a single iteration
            while( defined ReadKey(-1) ) {}
        }
    ReadMode 0;
    }
}

基于
mob
的回答,使用,我做了这个脚本来模拟更复杂的输入交互。最重要的区别是使用“rawInput”:
mob
建议:
rawInput(“”,1)
,我发现实际使用
rawInput(“>”)
(没有第二个参数)使事情更容易处理,并且提示“>”更有用

此代码接受命令和特殊键。此外,它还可以很好地显示,用作系统的交互式shell

DELETE
键将删除所有字符和
BACKSPACE
单个字符。
ESC
将退出shell。您可以添加更多键以包含箭头或任何其他执行特殊功能的键。此代码将打印出未包含在
if..elsif
(这样您就知道需要添加什么)


您可以从内到外执行命令

您使用的是什么操作系统?这可以准确地检测普通键和特殊键。但是,现在当我键入普通键时,同样的问题也会发生。例如,如果我点击“t”,我的函数会执行3次,但如果我点击向上箭头,我的函数会正确执行一次。因此,我不确定如何将其与ReadKeys结合使用获取有效的解决方案。@user3821320什么函数?您的问题中没有任何代码。对不起,我的意思是提示…即使我只按了一次键,但“回车键”提示仍会显示多次@hobbi我已使用此建议中的代码更新了我的问题…当我在“回车键”上按常规键时:提示,迭代将进行3次,在最后一次迭代中,它将显示“You hit the normal…key”@mob
use strict;use warnings;
while
语句中的
$keystroke
与循环中的
my($keystroke)
不同。我在尝试安装模块时出错。。。“cpan Term::TermKey”…第一个是“----PEVANS/Term-TermKey-0.16.tar.gz期间检测到的未满足的依赖项----“@user3821320 stackoverflow不是用于支持问题的。也许可以尝试提出RT票证?或者给我发电子邮件-地址遍布CPAN。谢谢!我整个上午都在寻找处理这些特殊字符的方法!不知道为什么要使用
$mode
变量。
while(defined ReadKey(-1)){
对我来说效果很好。很好的捕获…$mode变量对这个解决方案没有任何有用的意义,它是我的程序所需要的一个变量…我已经根据您的输入更新了答案…感谢@TJWRONA1992很好的开始,但是我看到一些细节:代码末尾缺少一个
ReadMode 0
,因此它将重置模式。所有箭头键都将返回“27”,这是顺序中的第一个。例如,向上是:27,91,65,向下是:27,91,66,因此对于代码,这两个键都是“27”(其余的被丢弃)。同样的情况也发生在上,所以我想这是图书馆的一部分。仅供参考,添加了@lepe建议的
ReadMode 0
,这很有帮助。这仍然不起作用,但有了这一更改,这至少是一个开始
use Term::ReadKey;

ReadMode('cbreak');

{
    #Temporarily turn off warnings so no messages appear for uninitialized $keystroke
    #that for some reason appears for the if statement
    no warnings;

    my $keystroke = '';

    while ($keystroke ne 'h') {

        print "\nEnter key: ";

        #Read user keystroke 
        $keystroke = ReadKey(0);

        #The first character for the arrow keys (ex. '^[[A') evaluates to 27 so I check for 
        #that
        if(ord($keystroke) == 27) {
            #Flush the rest of the characters from input buffer
            #This produces an 'Use of uninitialized value...' error
            #for the other two characters, hence 'no warnings' at the beginning.
            #This will ignore the other 2 characters and only cause a single iteration
            while( defined ReadKey(-1) ) {}
        }
    ReadMode 0;
    }
}
use warnings;
use strict;
use Term::RawInput;

sub out {
    my $out = shift;
    print "[ $out ]\n";
}

do {
    my ($keystroke,$special) = rawInput("> ");
    if($special eq 'ESC') {
        print "\n";
        exit;
    } elsif($special eq 'ENTER') {
        out($keystroke);
    } elsif($special ne 'DELETE') {
        if ($keystroke ne '') {
            out($keystroke);
        } else {
            print "'$special' key is not associated\n";
        }
    }
} while(1);