Enterを押さずに単一の文字を取得するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/174933

  •  05-07-2019
  •  | 
  •  

質問

Enterを押さずにRubyを使用してターミナルから単一のキーボード文字を取得するにはどうすればよいですか?私は試した Curses::getch, しかし、それは私にとってはうまくいきませんでした。

役に立ちましたか?

解決

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プラットフォームに移植できない場合があります)。その他の提案については、 http://www.rubyquiz.com/quiz5.html をご覧ください。 Windows。

他のヒント

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

require 'io/console'
STDIN.getch

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

  1. デフォルトのtty状態を台無しにすることができます。
  2. 制御文字を無視します(SIGINTの場合は^ Cなど)。

そのための簡単な修正は、以前のtty状態を保存し、次のパラメーターを使用することです:

  • -icanon -正規入力を無効にします(消去およびキル処理);
  • isig -特殊制御文字INTR、QUIT、およびSUSPに対する文字のチェックを有効にします。

最終的には、次のような関数になります。

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

  STDIN.getc.chr
ensure
  `stty #{state}`
end

生モード( 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ハンドラーは必要ないことに注意してください。

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

しかし、答えは、他の方法が機能しない一部の環境では依然として有用です。以下のコメントを読んでください。


最初にhighlineをインストールする必要があります:

gem install highline

次に、highlineメソッドが有効かどうか試してください:

require "highline/system_extensions"
include HighLine::SystemExtensions

print "Press any key:"
k = get_character
puts k.chr

そして、 curses アプリケーションを構築している場合、呼び出す必要があります

nocbreak

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top