Golang 从 stdin 读取,如何检测特殊键(输入,退格...等)

标签 go stdin tty pty

我有以下从标准输入读取用户输入的程序:

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 而 backspace 打印一个未定义的字符。

最佳答案

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 从 stdin 读取,如何检测特殊键(输入,退格...等),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40159137/

相关文章:

c - fgets 不阻塞输入 - C

perl - 写入STDOUT和向 "/dev/tty"打开的文件句柄有什么区别?

unix - Java程序标准输出和从前台分离

go - 从另一个没有重复的确定性 int 生成

go - 如何在一行代码中将 buf 分成两片?

go - 有没有一种在 golang 包之间共享结构的有效方法?

python - 在 python 中,将日志记录和 ncurses 转到单独的 TTY

amazon-web-services - 新的唯一键名称上的AWS Golang CreateSecret()ResourceExistsException

php - 如何将变量作为标准输入从 PHP 传递到命令行

c - 如何清除 C 中的输入缓冲区?