Golang如何在stdout上更新一个inplace字符串?

47 stdout go

我想输出到stdout并让输出"覆盖"前一个输出.

例如; 如果我输出On 1/10,我希望下一个输出On 2/10覆盖On 1/10.我怎样才能做到这一点?

zzz*_*zzz 82

stdout是一个流(io.Writer).您无法修改已写入的内容.什么可以被改变是如何的情况下,表示该流的其打印到终端.请注意,没有充分的理由假设这种情况.例如,用户可以随意将stdout重定向到管道或文件.

所以正确的方法是首先检查:

  • 如果标准输出到终端
  • 什么是终端覆盖线路/屏幕的程序

以上两个都不属于这个问题的范围,但我们假设终端是我们的设备.然后通常,打印:

fmt.Printf("\rOn %d/10", i)
Run Code Online (Sandbox Code Playgroud)

将覆盖终端中的上一行.\r代表carriage return,由许多终端实现为将光标移动到当前行的开头,因此提供"覆盖线"功能.

作为具有不同支持的"覆盖"的"其他"终端的示例,这里是操场上的示例.


Fra*_*yce 23

如果要将多行重写到输出,请使用此解决方案.例如,我使用这种方法制作了一个不错的Conway的"生命游戏"输出.

免责声明:这仅适用于ANSI终端,除此之外,使用fmt它也不是Go特定的答案.

fmt.Printf("\033[0;0H")
// put your other fmt.Printf(...) here
Run Code Online (Sandbox Code Playgroud)

简要说明:这是一个转义序列,它告诉ANSI终端将光标移动到屏幕上的特定位置.这\033[就是所谓的转义序列,它0;0H是告诉终端将光标移动到终端的第0行第0列的代码类型.

资料来源:https://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements

  • 令人敬畏的维基"康威生活游戏"...感谢一个链接 (2认同)
  • 这个解决方案在OSX终端中非常适合我.接受的答案实际上对我没有任何作用. (2认同)

abo*_*nec 8

一个将替换整个字符串的字符串的解决方案

fmt.Printf("\033[2K\r%d", i)

例如,它可以正确打印10到0:

for i:= 10; i>=0; i-- {
    fmt.Printf("\033[2K\r%d", i)
    time.Sleep(1 * time.Second)
}
fmt.Println()
Run Code Online (Sandbox Code Playgroud)

以前的答案不能解决。