Как получить один символ без нажатия enter?
Как я могу получить один символ клавиатуры из терминала с Ruby без нажатия enter? Я пытался!--0-->, но это не сработало для меня.
6 ответов
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.
@Jay дал отличный ответ, но есть две проблемы:
- вы можете испортить состояние tty по умолчанию;
- вы игнорируете управляющие символы (^C для SIGINT и т. д.).
простое исправление для этого-сохранить предыдущее состояние tty и использовать следующие параметры:
-
-icanon
- отключить канонический ввод (обработка стирания и уничтожения); -
isig
включить проверку персонажей на особый контроль персонажи INTR, QUIT и SUSP.
В конце концов у вас будет такая функция:
def get_char
state = `stty -g`
`stty raw -echo -icanon isig`
STDIN.getc.chr
ensure
`stty #{state}`
end
режим 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
обратите внимание, что вам не нужен специальный Обработчик SIGINT для неблокирующей версии, так как tty находится только в режиме raw в течение короткого момента.
Примечание: это и старый ответ и решение больше не работает на большинстве систем.
но ответ все равно может быть полезен для некоторых сред, где другие методы не работают. Пожалуйста, прочитайте комментарии ниже.
сначала вам нужно установить highline:
gem install highline
затем попробуйте, если метод highline работает для вас:
require "highline/system_extensions"
include HighLine::SystemExtensions
print "Press any key:"
k = get_character
puts k.chr
и если вы строите проклятие приложение, вам нужно позвонить
nocbreak
http://www.ruby-doc.org/stdlib-1.9.3/libdoc/curses/rdoc/Curses.html#method-c-cbreak