提问人:Qwib 提问时间:12/9/2022 更新时间:12/13/2022 访问量:88
Ruby:在 getch 上按箭头键后带有 gets 的“寄生虫”字符
Ruby: "Parasite" characters with gets after pressing arrow key on getch
问:
我一直在寻找一种方法,在我的程序中实现“按任意键继续”功能,并认为我会使用 $stdin.getch。
似乎在大多数情况下都有效,但我注意到,如果我在提示按任何键时按下箭头键,下一个 get 命令将在它返回的字符串的开头有“寄生虫”字符,大概是因为箭头键给出了几个字符作为输入,只有第一个字符被 getch 读取, 其余的被保存以备下次获取。更准确地说,当我按向右箭头键时,getch 返回“\e”,下一个 get 返回带有“[C”前缀。
我想也许我必须刷新/清空 stdin 缓冲区,但 flush、iflush 和 ioflush 似乎没有任何作用。尝试在 gets 之前将 '' 写入 stdin 也不起作用。我也尝试过在 $stdin 上同步和 fsync,但它也不起作用。知道问题可能是什么吗?
答:
0赞
Stefan
12/13/2022
#1
getch
将 IO 置于所谓的原始模式,然后读取单个字符。
但是,有些键在按下时会生成多个字符。例如,向右箭头键通常配置为生成 3 字节序列,该序列是“光标前进”的 ANSI 转义序列。→\e[C
现在,如果你尝试通过 来读取该序列,你只会得到 ,即第一个字符。所有后续字符(此处:和)将由下一个读取操作返回。getch
\e
[
C
您可以手动将 stdin 置于原始
模式,而不是通过 读取单个字符,并通过 readpartial
读取所有可用字符(不超过合理限制),例如:getch
$stdin.raw { |io| io.readpartial(100) }
上面在按下时返回整个序列,其行为类似于单字符键。"\e[C"
→getch
请注意,终端仿真器和操作系统的行为不同。以上对我来说很好,但您可能想自己在各种系统上测试该解决方案。
评论
getch
\e
ESC [C
$stdin.getch while $stdin.ready?
$stdin.getch