我该如何让Perl逐个字符从标准输入中获取输入?

6
我在Perl方面有些基础(相较于这里的人来说),我已经了解到如何通过命令提示符编写程序来完成许多任务。曾经,我想编写一个命令提示符游戏,它可以构建迷宫并允许我解决它。除了高质量的图形外,唯一缺少的是我无法在迷宫中使用WASD控件而不必在每次移动后按Enter键。
为使我的游戏有效,我希望能够让Perl从STDIN中接收单个字符输入,而不需要使用默认的换行符“\n”之类的分隔符分离输入。我该如何实现这一点?
我试着在线上和我的书籍中寻找简单的答案,但似乎没有找到。我尝试过设置“$/ = ''”,但这似乎绕过了所有输入。我认为可能有一个非常简单的答案来回答我的问题,但我也担心这是不可能的。
此外,“$/ = ''”是否确实绕过了输入,还是它接收输入得如此之快,以至于如果我没有按下键,就会认为没有任何输入?

2
Term::ReadKey - ikegami
可能是如何在Windows上使用Perl从STDIN读取单个字符?的重复问题。 - Eugen Konkov
4个回答

4

IO::Prompt 可以用于:

#!/usr/bin/env perl

use strict;
use warnings;

use IO::Prompt;

my $key = prompt '', -1;
print "\nPressed key: $key\n";

perldoc -v '$/'相关摘录,与设置$/ = ''有关:

输入记录分隔符,默认为换行符。这会影响Perl对“行”的理解。工作方式类似于awk的RS变量,包括将空行视为空终止符,如果设置为空字符串(空行不能包含任何空格或制表符)。


3
达到目标的最短方式是使用这个特殊的结构:
$/ = \1;

这告诉perl一次读取一个字符。下一次从任何流中读取(不仅限于STDIN)时。

my $char = <STREAM>;

它将每次分配读取1个字符。根据perlvar的说明,“将 $/ 设置为整数引用、包含整数的标量或可转换为整数的标量将尝试读取记录而不是行,最大记录大小为引用的整数字符数。”


OP的问题是关于交互式地读取单个按键,"而不需要使用类似默认的\n这样的分隔符”。这需要更改终端设置,而您的代码并没有做到这一点。 - melpomene
你是...欢迎的吗?我的意思是,“这个答案没有用”这句话就是那个踩的按钮所表达的。 - melpomene
2
并不完全符合描述,但回答了标题... STDIN 并不总是来自终端,所以我给加上一个赞。 - David L.
这可能与问题的主体不符,但它确切地回答了标题中的问题。标题和问题主体之间的不匹配是完全不同的问题。 - William Pursell

1
如果您正在使用*nix,您会发现Curses非常有用。
它有一个getch方法可以满足您的需求。 Term::TermKey也看起来是一个潜在的解决方案。

0

IO::Prompt不再维护,但IO::Prompter有一个不错的例子(引自该网站):

use IO::Prompter;
 
# This call has no automatically added options...
my $assent = prompt "Do you wish to take the test?", -yn;
 
{
    use IO::Prompter [-yesno, -single, -style=>'bold'];
 
    # These three calls all have: -yesno, -single, -style=>'bold' options
    my $ready = prompt 'Are you ready to begin?';
    my $prev  = prompt 'Have you taken this test before?';
    my $hints = prompt 'Do you want hints as we go?';
}
 
# This call has no automatically added options...
scalar prompt 'Type any key to start...', -single;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接