Golang 从标准输入读取,如何检测特殊键(回车、退格...等)
Posted
技术标签:
【中文标题】Golang 从标准输入读取,如何检测特殊键(回车、退格...等)【英文标题】:Golang reading from stdin, how to detect special keys (enter, backspace... etc) 【发布时间】:2017-03-02 17:33:27 【问题描述】:我有以下程序从标准输入读取用户输入:
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 循环中放置某种条件,以便在用户按下“enter”(例如)时“中断”或在用户按下(退格)时从字符串中删除一个字符。但是,我无法弄清楚这两个键的字节数组或字符串表示形式是什么。我该如何解决这个问题? enter 只打印一个 \w 并退格打印一个未定义的字符。
【问题讨论】:
在 unix 系统上,“返回”很可能是"\n"
和 "\b"
或 "\x7f"
字符串形式的退格之一。
为什么不使用github.com/nsf/termbox-go
和/或github.com/jteeuwen/keyboard/termbox
(使用前者)?我有一种感觉,你选择了一种相当奇特的方法来解决你的任务。相反,您应该将终端切换到“原始”模式并处理它发送给您的任何数据。 termbox
为您完成繁重的工作。
考虑使用godoc.org 来大致了解这些软件包可以为您做什么(并搜索其他选项)。
这里是a demo code dealing with keyboard input using termbox-go
。
【参考方案1】:
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
如果您不介意按 Enter 按钮,那么上面的代码如下所示:-
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)
【讨论】:
以上是关于Golang 从标准输入读取,如何检测特殊键(回车、退格...等)的主要内容,如果未能解决你的问题,请参考以下文章