Frage

Wie kann ich ein einzelnes Zeichen auf der Tastatur aus dem Terminal mit Rubin erhalten, ohne Enter-Taste? Ich versuchte Curses::getch, aber das hat für mich wirklich nicht.

War es hilfreich?

Lösung

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

(getestet auf meinem OS X-System kann nicht auf alle Ruby-Plattformen portierbar sein). Siehe http://www.rubyquiz.com/quiz5.html für einige weitere Vorschläge, auch für Fenster.

Andere Tipps

Da Rubin 2.0.0 gibt es eine 'io / console' in der stdlib mit dieser Funktion

require 'io/console'
STDIN.getch

@Jay gab eine große Antwort, aber es gibt zwei Probleme:

  1. Sie können vermasseln Standard tty Zustand;
  2. Sie ignorieren Steuerzeichen (^ C für SIGINT, etc).

Eine einfache Lösung für das heißt vorherigen tty Zustand und die Verwendung folgender Parameter speichern:

  • -icanon - deaktivieren kanonischen Eingang (ERASE und KILL-Verarbeitung);
  • isig - ermöglichen die Überprüfung von Zeichen gegen die speziellen Steuerzeichen INTR, QUIT und SUSP
  • .

Am Ende würden Sie eine Funktion wie diese haben:

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

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

Raw-Modus (stty raw -echo) leider verursacht Steuer-C als ein Zeichen gesendet zu bekommen, nicht als SIGINT. Also, wenn Sie eingeben möchten blockiert wie oben, aber ermöglichen dem Benutzer die Kontrolle-C zu schlagen, das Programm zu stoppen, während es wartet, stellen Sie sicher, dies zu tun:

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

Und wenn Sie nicht blockierenden Eingang wollen - das heißt, in regelmäßigen Abständen überprüfen, ob der Benutzer einen Schlüssel, aber in der Zwischenzeit gedrückt hat, gehen andere Dinge tun - dann können Sie dies tun:

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

Beachten Sie, dass Sie nicht einen speziellen SIGINT-Handler für die nicht-blockierende Version brauchen, da die tty nur im Raw-Modus für einen kurzen Moment sind.

Hinweis: Dies ist und alte Antwort und die Lösung nicht mehr funktioniert auf den meisten Systemen

.

Aber die Antwort könnte noch für einige Umgebungen nützlich sein, wo die anderen Methoden nicht funktionieren. Bitte lesen Sie die Kommentare unten.


Zuerst müssen Sie Highline installieren:

gem install highline

Dann versuchen Sie, wenn die Highline-Methode für Sie:

require "highline/system_extensions"
include HighLine::SystemExtensions

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

Und wenn Sie bauen Flüche Anwendung, müssen Sie anrufen

nocbreak

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

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top