如何在Go中等待用户输入时打印到控制台?

时间:2016-10-03 20:14:01

标签: go console

我正在编写一个交互式应用程序,它接受循环中的用户输入并在后台打印出响应。我的代码的阅读器部分如下:

scanner := bufio.NewReader(os.Stdin)
for {
    fmt.Print(":: ")                // prompt for user to enter stuff
    in,_:=scanner.ReadString('\n')
}

然而,当我在等待用户输入时,我想打印一些我通过网络获得的异步数据,如下所示:

>> Some text
>> :: Hi I'm the user and I'm

现在有些背景数据到了:

>> Some text
>> This data was printed while user was inputting
>> :: Hi I'm the user and I'm

现在用户可以完成输入:

>> Some text
>> This data was printed while user was inputting
>> :: Hi I'm the user and I'm entering some text
>> :: 

我认为后台例程需要扫描stdin文本,以某种方式擦除它,打印自己的数据,然后恢复原始文本。我不知道如何扫描未通过回车键输入的文本,或如何清除行。我该怎么做呢?

1 个答案:

答案 0 :(得分:1)

要清除一行,您可以使用\r将光标返回到行首,然后用空格替换行上的所有字符,然后发出另一个\r返回到行的开头再次排队。例如(如果需要,添加更多空格):

fmt.Printf("\r                                                        \r")

现在,您可以在用户输入的数据之上打印背景数据。

那么你如何重新打印用户输入的数据?您无法从终端本身读取它,因此您必须在输入时将其保存在某个位置。执行此操作的一种方法是禁用终端上的输入缓冲,以便您键入的每个字符立即刷新到stdin,您可以在其中读取它。例如:

var input []byte
reader := bufio.NewReader(os.Stdin)
// disables input buffering
exec.Command("stty", "-F", "/dev/tty", "cbreak", "min", "1").Run()
// append each character that gets typed to input slice
for {
        b, err := reader.ReadByte()
        if err != nil {
                panic(err)
        }
        input = append(input, b)
}

因此,当您需要插入背景数据时,首先清除该行,然后打印您的背景数据,最后在下一行打印输入变量的内容。