Golang 从标准输入读取,如何检测特殊键(回车、退格...等)

     2023-03-17     20

关键词:

【中文标题】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)
         

 

【讨论】:

如何使用 Linux 系统调用检测何时按下某个键

...的命令来完成执行,因此我试图找到一种不使用read(...)从标准输入输出读取击键的方法,因为我不希望 查看详情

你如何从标准输入读取?

】你如何从标准输入读取?【英文标题】:Howdoyoureadfromstdin?【发布时间】:2010-11-2920:10:12【问题描述】:我正在尝试做一些codegolf挑战,但它们都需要从stdin获取输入。我如何在Python中获得它?【问题讨论】:【参考方案1】:来... 查看详情

golang读写数据---上(代码片段)

GoLang读写数据---上读取用户的输入scanfscan和scanlnFscan系列和Sscanf系列bufio文件读写读文件其他类似函数:compress包:读取压缩文件写文件实例演示读取用户的输入我们如何读取用户的键盘(控制台)输入呢?从... 查看详情

确定子进程是不是从标准输入读取

】确定子进程是不是从标准输入读取【英文标题】:Determineifasubprocessreadsfromstdin确定子进程是否从标准输入读取【发布时间】:2020-11-2313:16:33【问题描述】:我有一个通过subprocess.run(...)启动其他进程的python脚本。通常这样的进... 查看详情

PHP CLI:如何从 TTY 读取单个字符的输入(无需等待回车键)?

】PHPCLI:如何从TTY读取单个字符的输入(无需等待回车键)?【英文标题】:PHPCLI:HowtoreadasinglecharacterofinputfromtheTTY(withoutwaitingfortheenterkey)?【发布时间】:2011-04-1016:58:00【问题描述】:我想从PHP中的命令行一次读取一个字符,但... 查看详情

如何从标准输入读取 dask 数据帧?

】如何从标准输入读取dask数据帧?【英文标题】:Howtomakedaskdataframereadfromstdin?【发布时间】:2021-11-0517:34:45【问题描述】:对于dask数据框,我想将sys.stdin作为输入dask.dataframe.read_csv(sys.stdin,sep="",header=None)但是,dask.dataframe只接受... 查看详情

如何从标准输入读取一行,阻塞直到找到换行符?

】如何从标准输入读取一行,阻塞直到找到换行符?【英文标题】:Howtoreadalinefromstdin,blockinguntilthenewlineisfound?【发布时间】:2012-08-2810:35:33【问题描述】:我正在尝试从命令行的标准输入一次读取任意长度的一行。我不确定我... 查看详情

如何从 Java 中的标准输入中读取整数值

】如何从Java中的标准输入中读取整数值【英文标题】:HowtoreadintegervaluefromthestandardinputinJava【发布时间】:2011-01-3103:43:21【问题描述】:我可以使用什么类来读取Java中的整数变量?【问题讨论】:【参考方案1】:检查这个:publ... 查看详情

wpf限制textbox只能输入数字及特殊键

原文:wpf限制textbox只能输入数字及特殊键使用vs2015进行wpf设计时,发现限制输入数字时,Keydown事件无法检测到空格的输入,后经过查资料调试,发现PreviewKeyDown可以满足检测输入所有值合法性的要求,我的textbox输入框中只允许输... 查看详情

如何在可用时从标准输入读取行(否则阻止)?

】如何在可用时从标准输入读取行(否则阻止)?【英文标题】:Howtoreadlinesfromstdinwheneveravailable(blockotherwise)?【发布时间】:2012-04-1300:36:36【问题描述】:在下面的代码中,p00是一个命名管道,由mkfifop00创建。在控制台1中,我... 查看详情

如何逐行读取标准输入?

】如何逐行读取标准输入?【英文标题】:Howtoreadfromstandardinputlinebyline?【发布时间】:2011-06-0221:47:28【问题描述】:从标准输入逐行读取的Scala方法是什么?类似于等效的java代码:importjava.util.Scanner;publicclassScannerTestpublicstaticvoid... 查看详情

从标准输入读取所有文本到字符串

】从标准输入读取所有文本到字符串【英文标题】:Readalltextfromstdintoastring【发布时间】:2015-08-0702:13:55【问题描述】:我正在用Node.js编写一个程序,它(在某些情况下)想要充当一个简单的过滤器:从标准输入读取所有内容(... 查看详情

如何将多行输入从标准输入读取到变量中以及如何在 shell(sh,bash)中打印出来?

】如何将多行输入从标准输入读取到变量中以及如何在shell(sh,bash)中打印出来?【英文标题】:Howtoreadmutlilineinputfromstdinintovariableandhowtoprintoneoutinshell(sh,bash)?【发布时间】:2010-09-1719:08:49【问题描述】:我想做的是:将多行... 查看详情

如何使用媒体键读取 USB 键盘的键码

...:是否可以使用特殊的iOSAPI或通过通用TextInput字段读取非标准键的键码?我有一个带有特殊按钮的多媒体键盘,我想让我的iPad应用程序知道这些键码。我知道iOS已经可以使用其中的一些(即音量增大/减小、下一首/上一首曲目)... 查看详情

测试从标准输入读取并写入标准输出的 java 程序

】测试从标准输入读取并写入标准输出的java程序【英文标题】:Testjavaprogramsthatreadfromstdinandwritetostdout【发布时间】:2012-10-3100:35:46【问题描述】:我正在为Java编程竞赛编写一些代码。程序的输入使用标准输入给出,输出在标准... 查看详情

有没有办法在标准 C++ 中直接从键盘读取输入? [复制]

】有没有办法在标准C++中直接从键盘读取输入?[复制]【英文标题】:IsthereawaytoreadinputdirectlyfromthekeyboardinstandardC++?[duplicate]【发布时间】:2010-10-2812:23:06【问题描述】:我知道有std::cin,但这需要用户输入一个字符串,然后按ENTE... 查看详情

从键盘读取输入而不按回车[重复]

】从键盘读取输入而不按回车[重复]【英文标题】:readinginputfromthekeyboardwithoutpressingenter[duplicate]【发布时间】:2012-12-2301:28:42【问题描述】:可能重复:C/C++:CapturecharactersfromstandardinputwithoutwaitingforentertobepressedHowdoyoudonon-blockingcons... 查看详情

while(cin)是啥意思(c++)

...候会运行IF中的内容什么时候跳过IFcin是C++编程语言中的标准输入流对象,即istream类的对象。cin主要用于从标准输入读取数据,这里的标准输入,指的是终端的键盘。此外,cout是流的对象,即ostream类的对象,cerr是标准错误输出... 查看详情