2016-10-20 57 views
0

我有以下的程序,它從標準輸入讀取用戶輸入:Golang從標準輸入,如何檢測特殊鍵(回車,退格...等),閱讀

var input string = "" 
      exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run() 
      exec.Command("stty", "-F", "/dev/tty", "-echo").Run() 
      var b []byte = make([]byte, 1) 
      for { 
       input += string(b) 
      } 

我希望把某種條件內for循環,這樣當用戶按下「回車」(例如)時我可以「斷開」,或者當用戶按下(退格鍵)時從字符串中移除一個字符。但是,我無法弄清楚這兩個鍵的字節數組或字符串表示是什麼。我如何去解決這個問題?進入只是打印\ w和退格prins一個未定義的字符。

+0

在unix系統上,「return」很可能是'「\ n」',並以字符串形式退格爲「\ b」或「\ x7f」。 – Vatine

+0

爲什麼不使用'github.com/nsf/termbox-go'和/或'github.com/jteeuwen/keyboard/termbox'(它使用前者)?我有一種感覺,你選擇了一種相當奇特的方法來解決你的任務。相反,您應該將終端切換到「原始」模式並處理髮送給您的任何數據。 'termbox'爲你做了繁重的工作。 – kostix

+0

請考慮使用http://godoc.org獲取這些軟件包可以爲您做什麼(以及搜索其他選項)的概述。 – kostix

回答

2

您的用例在此blog post中解釋。剛剛越過張貼在博客中引用了必要的解決方案: -

package main 

import (
    "fmt" 
    term "github.com/nsf/termbox-go" 
) 

func reset() { 
    term.Sync() // cosmestic purpose 
} 

func main() { 
    err := term.Init() 
    if err != nil { 
     panic(err) 
    } 

    defer term.Close() 

    fmt.Println("Enter any key to see their ASCII code or press ESC button to quit") 

keyPressListenerLoop: 
    for { 
     switch ev := term.PollEvent(); ev.Type { 
     case term.EventKey: 
      switch ev.Key { 
      case term.KeyEsc: 
       break keyPressListenerLoop 
      case term.KeyF1: 
       reset() 
       fmt.Println("F1 pressed") 
      case term.KeyF2: 
       reset() 
       fmt.Println("F2 pressed") 
      case term.KeyF3: 
       reset() 
       fmt.Println("F3 pressed") 
      case term.KeyF4: 
       reset() 
       fmt.Println("F4 pressed") 
      case term.KeyF5: 
       reset() 
       fmt.Println("F5 pressed") 
      case term.KeyF6: 
       reset() 
       fmt.Println("F6 pressed") 
      case term.KeyF7: 
       reset() 
       fmt.Println("F7 pressed") 
      case term.KeyF8: 
       reset() 
       fmt.Println("F8 pressed") 
      case term.KeyF9: 
       reset() 
       fmt.Println("F9 pressed") 
      case term.KeyF10: 
       reset() 
       fmt.Println("F10 pressed") 
      case term.KeyF11: 
       reset() 
       fmt.Println("F11 pressed") 
      case term.KeyF12: 
       reset() 
       fmt.Println("F12 pressed") 
      case term.KeyInsert: 
       reset() 
       fmt.Println("Insert pressed") 
      case term.KeyDelete: 
       reset() 
       fmt.Println("Delete pressed") 
      case term.KeyHome: 
       reset() 
       fmt.Println("Home pressed") 
      case term.KeyEnd: 
       reset() 
       fmt.Println("End pressed") 
      case term.KeyPgup: 
       reset() 
       fmt.Println("Page Up pressed") 
      case term.KeyPgdn: 
       reset() 
       fmt.Println("Page Down pressed") 
      case term.KeyArrowUp: 
       reset() 
       fmt.Println("Arrow Up pressed") 
      case term.KeyArrowDown: 
       reset() 
       fmt.Println("Arrow Down pressed") 
      case term.KeyArrowLeft: 
       reset() 
       fmt.Println("Arrow Left pressed") 
      case term.KeyArrowRight: 
       reset() 
       fmt.Println("Arrow Right pressed") 
      case term.KeySpace: 
       reset() 
       fmt.Println("Space pressed") 
      case term.KeyBackspace: 
       reset() 
       fmt.Println("Backspace pressed") 
      case term.KeyEnter: 
       reset() 
       fmt.Println("Enter pressed") 
      case term.KeyTab: 
       reset() 
       fmt.Println("Tab pressed") 

      default: 
       // we only want to read a single character or one key pressed event 
       reset() 
       fmt.Println("ASCII : ", ev.Ch) 

      } 
     case term.EventError: 
      panic(ev.Err) 
     } 
    } 
} 

樣本輸出

Enter any key to see their ASCII code or press ESC button to quit 
Tab pressed 
ASCII : 49 
ASCII : 50 
ASCII : 51 
ASCII : 52 
ASCII : 53 
F1 pressed 
Arrow Up pressed 
Arrow Left pressed 
Arrow Down pressed 
Arrow Right pressed 
Arrow Up pressed 

如果你不介意打回車按鈕,然後在上面的代碼看起來象下面這樣: -

package main 

import (
     "fmt" 
     "os" 
     "bufio" 
) 



func main() { 

     fmt.Println("Press ESC button or Ctrl-C to exit this program") 
     fmt.Println("Press any key to see their ASCII code follow by Enter") 

     for { 
       // only read single characters, the rest will be ignored!! 
       consoleReader := bufio.NewReaderSize(os.Stdin, 1) 
       fmt.Print(">") 
       input, _ := consoleReader.ReadByte() 

       ascii := input 

       // ESC = 27 and Ctrl-C = 3 
       if ascii == 27 || ascii == 3 { 
         fmt.Println("Exiting...") 
         os.Exit(0) 
       } 

       fmt.Println("ASCII : ", ascii) 
     } 

} 
相關問題