我一直在寻找一种实现"按任意键继续"的方法。我想我应该使用$stdin.getch.
似乎在大多数情况下都有效,但我注意到,如果我在提示按下任何键时按下箭头键,下一个gets命令将具有"寄生虫";它返回的字符串开头的字符,可能是因为箭头键提供了几个字符作为输入,只有第一个字符被getch读取,其余的保存到下一个gets。更准确地说,当我按下右箭头键时,getch返回& ';e"下一个得到的回报有一个"[C">
我想也许我必须冲洗/清空stdin缓冲区,但冲洗,iflush和ioflush似乎不做任何事情。尝试在get之前将"写入stdin也不工作。我也试过在$stdin上同步和fsync,但它也不起作用。知道是什么问题吗?
getch
将IO置于所谓的原始模式,然后读取单个字符。
但是,有些键在按下时可以生成多个字符。例如,右箭头键→通常配置为生成3字节序列e[C
,这是用于"光标向前"的ANSI转义序列。
现在,如果您尝试通过getch
读取该序列,您将只得到e
,即第一个字符。所有后面的字符(这里是:[
和C
)将在下一次读操作时返回。
不通过getch
读取单个字符,您可以手动将stdin置于raw
模式,并通过readpartial
读取所有可用字符(不超过合理限制),例如:
$stdin.raw { |io| io.readpartial(100) }
当按→时,上面返回整个"e[C"
序列,并且对于单字符键的行为与getch
相似。
注意终端模拟器和操作系统的行为不同。上面的工作对我来说很好,但是你可能想要自己在不同的系统上测试这个解决方案。