【问题标题】:Read a character from standard input in Go (without pressing Enter)从 Go 中的标准输入读取一个字符(不按 Enter)
【发布时间】:2013-03-01 13:37:46
【问题描述】:

我希望我的应用显示:

press any key to exit ...

当我按下 any 键时退出。

我怎样才能做到这一点?

注意:我已经用谷歌搜索了,但我发现所有内容都需要在最后按 Enter。我想要 C# 中的 Console.ReadKey() 之类的东西。

我正在运行 MS Windows。

【问题讨论】:

  • @jnml 没有;这不是重复的。我之前已经看到过这个问题,并且使用答案中提供的代码,您仍然需要在标准输入处按 Enter。
  • 口是心非只是关于这个问题,而不是关于它的任何答案。

标签: go stdin


【解决方案1】:

这是运行 UNIX 系统的最小工作示例:

package main

import (
    "fmt"
    "os"
    "os/exec"
)

func main() {
    // disable input buffering
    exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
    // do not display entered characters on the screen
    exec.Command("stty", "-F", "/dev/tty", "-echo").Run()

    var b []byte = make([]byte, 1)
    for {
        os.Stdin.Read(b)
        fmt.Println("I got the byte", b, "("+string(b)+")")
    }
}

【讨论】:

  • 如何让输入的字符重新显示在屏幕上?
  • Ibolit:它们已经显示在示例中。要只显示字符,fmt.Print(string(b)) 应该可以工作。
  • lbolit:使用exec.Command("stty", "-F", "/dev/tty", "echo").Run() 让他们回来。
【解决方案2】:

termbox-go 是一个轻量级的 Go-native 包,它提供了一些基本的终端控制。包括以原始模式获取输入的能力(一次读取一个字符,没有默认的行缓冲行为)。

它在不同系统之间也具有相当好的兼容性。

并且keyboard 扩展了 termbox-go 以提供一些额外的键盘功能,例如多键快捷键和序列。

【讨论】:

  • 这不是raw_mode的定义。
【解决方案3】:

go-termbox 非常重量级。它想接管整个终端窗口。例如,它在启动时清除屏幕,这可能不是您想要的。

我把它放在 OSX 上。只是一个小小的 getchar():

https://github.com/paulrademacher/climenu/blob/master/getchar.go

【讨论】:

  • 也适用于 linux,但它从终端读取,而不是标准输入(可能是管道)
【解决方案4】:

你可以使用这个库(我的):https://github.com/eiannone/keyboard

这是获取单次击键的示例:

char, _, err := keyboard.GetSingleKey()
if (err != nil) {
    panic(err)
}
fmt.Printf("You pressed: %q\r\n", char)

【讨论】:

    【解决方案5】:

    “golang.org/x/term”包允许您将标准输入切换到原始模式以一次读取每个字节。

    package main
    
    import (
        "fmt"
        "os"
    
        "golang.org/x/term"
    )
    
    func main() {
        // switch stdin into 'raw' mode
        oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
        if err != nil {
            fmt.Println(err)
            return
        }
        defer term.Restore(int(os.Stdin.Fd()), oldState)
    
        b := make([]byte, 1)
        _, err = os.Stdin.Read(b)
        if err != nil {
            fmt.Println(err)
            return
        }
        fmt.Printf("the char %q was hit", string(b[0]))
    }
    

    【讨论】:

      【解决方案6】:

      您可以在原始模式下从终端读取单个按键。 Here 是一个应该为你的程序提供原始终端模式的包。抓住:它只适用于 Linux。

      【讨论】:

        【解决方案7】:

        试试这个 - http://play.golang.org/p/kg-QirlucY

        只需阅读func main末尾的os.Stdin即可

        【讨论】:

        • 这段代码演示了如何使用SetConsoleMode。如果想要“按 Enter 继续”,那么os.Stdin.Read([]byte{0}) 就足够了。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-02-19
        • 2013-03-16
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多