44

Enterキーを押さずにRubyを使用して端末からキーボード文字を1つ取得するにはどうすればよいですか? 試してみCurses::getchましたが、うまくいきませんでした。

4

6 に答える 6

68

Ruby 2.0.0 以降、この機能を備えた stdlib に「io/console」があります。

require 'io/console'
STDIN.getch
于 2014-11-19T16:23:17.430 に答える
37

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

(私の OS X システムでテストしましたが、すべての Ruby プラットフォームに移植できるわけではありません)。Windows 用を含む追加の提案については、 http://www.rubyquiz.com/quiz5.htmlを参照してください。

于 2008-10-06T16:14:35.223 に答える
21

@Jay は素晴らしい答えを出しましたが、2 つの問題があります。

  1. デフォルトの tty 状態を台無しにすることができます。
  2. 制御文字 (SIGINT の ^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
于 2013-01-25T17:49:12.170 に答える
14

raw モード ( stty raw -echo) は残念ながら、control-C を SIGINT ではなく文字として送信します。したがって、上記のように入力をブロックしたいが、待機中にユーザーが control-C を押してプログラムを停止できるようにする場合は、次のようにしてください。

Signal.trap("INT") do # SIGINT = control-C
  exit
end

また、非ブロック入力が必要な場合、つまり、ユーザーがキーを押したかどうかを定期的に確認し、その間に他のことを行う場合は、次のようにします。

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

非ブロッキング バージョンでは、tty が raw モードになるのはほんの一瞬なので、特別な SIGINT ハンドラは必要ないことに注意してください。

于 2011-11-25T21:13:36.517 に答える
13

注:これは古い回答であり、ソリューションはほとんどのシステムでは機能しなくなりました。

ただし、他の方法が機能しない一部の環境では、答えが依然として役立つ場合があります。以下のコメントをお読みください。


まず、highline をインストールする必要があります。

gem install highline

次に、ハイライン法がうまくいくかどうか試してください。

require "highline/system_extensions"
include HighLine::SystemExtensions

print "Press any key:"
k = get_character
puts k.chr
于 2010-10-21T01:51:51.917 に答える
0

また、cursesアプリケーションを作成している場合は、呼び出す必要があります。

nocbreak

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/curses/rdoc/Curses.html#method-c-cbreak

于 2012-11-30T21:43:09.570 に答える