如何在不按Enter的情况下获得单个角色?

Nin*_*ino 39 ruby getch

如何在不按Enter键的情况下从终端获取单个键盘字符?我试过了Curses::getch,但这对我没用.

iNe*_*cas 55

从ruby 2.0.0开始,stdlib中有一个带有此功能的'io/console'

require 'io/console'
STDIN.getch
Run Code Online (Sandbox Code Playgroud)

  • 如果你之后检查control-C,这很有用:`exit(1)if char =="\ u0003"`. (9认同)

Jay*_*Jay 33

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/2999

#!/usr/bin/ruby

begin
  system("stty raw -echo")
  str = STDIN.getc
ensure
  system("stty -raw echo")
end
p str.chr
Run Code Online (Sandbox Code Playgroud)

(在我的OS X系统上测试过,可能无法移植到所有Ruby平台).有关其他一些建议,请参阅http://www.rubyquiz.com/quiz5.html,包括Windows.

  • 是的,只需使用 str.chr 来获取与数值对应的字符。我已经更新了帖子以反映这一点 (2认同)
  • Andrew 在下面的回答(2013 年 1 月 25 日 17:49)更好。 (2认同)

And*_*rew 19

@Jay给出了一个很好的答案,但有两个问题:

  1. 你可以搞乱默认的tty状态;
  2. 您忽略控制字符(SIGC的^ C等).

一个简单的解决方法是保存以前的tty状态并使用以下参数:

  • -icanon - 禁用规范输入(ERASE和KILL处理);
  • isig - 根据特殊控制字符INTR,QUIT和SUSP启用字符检查.

最后你会有这样的函数:

def get_char
  state = `stty -g`
  `stty raw -echo -icanon isig`

  STDIN.getc.chr
ensure
  `stty #{state}`
end
Run Code Online (Sandbox Code Playgroud)


Ale*_*fee 14

stty raw -echo不幸的是,raw mode()导致control-C作为一个字符而不是一个SIGINT被发送.因此,如果你想要像上面那样阻塞输入,但是允许用户点击control-C以在程序等待时停止程序,请确保执行此操作:

Signal.trap("INT") do # SIGINT = control-C
  exit
end
Run Code Online (Sandbox Code Playgroud)

如果你想要非阻塞输入 - 也就是说,定期检查用户是否按下了一个键,同时又去做其他的东西 - 那么你可以这样做:

require 'io/wait'

def char_if_pressed
  begin
    system("stty raw -echo") # turn raw input on
    c = nil
    if $stdin.ready?
      c = $stdin.getc
    end
    c.chr if c
  ensure
    system "stty -raw echo" # turn raw input off
  end
end

while true
  c = char_if_pressed
  puts "[#{c}]" if c
  sleep 1
  puts "tick"
end
Run Code Online (Sandbox Code Playgroud)

请注意,对于非阻塞版本,您不需要特殊的SIGINT处理程序,因为tty仅在原始模式下短暂停留.


mit*_*mit 13

注意:这是旧的答案,解决方案不再适用于大多数系统.

但是对于某些环境,其他方法不起作用,答案仍然有用.请阅读以下评论.


首先你必须安装highline:

gem install highline
Run Code Online (Sandbox Code Playgroud)

然后尝试高线方法是否适合您:

require "highline/system_extensions"
include HighLine::SystemExtensions

print "Press any key:"
k = get_character
puts k.chr
Run Code Online (Sandbox Code Playgroud)

  • 警告:最近的提交已从highline删除此功能.请参阅https://github.com/JEG2/highline/issues/50 (4认同)
  • 这不起作用:它要求您按 <enter> 键。顺便说一句,它也接受 \n 字符。 (2认同)