如何在输出时进行输入?

huangapple go评论82阅读模式
英文:

How to take input when outputting?

问题

我正在尝试实现一种将大量信息记录到控制台的应用程序(例如,从0到1000000000000的数字),并且能够通过在控制台中输入命令(例如“stop”)来停止执行。

我想到了使用goroutines的方法,但是我无法输入命令,因为输入字段正在变为输出。

以下是我的代码:

package main

import (
	"bufio"
	"os"
)

var process bool = true

func commandHandler() {
	reader := bufio.NewReader(os.Stdin)
	for process {
		text, _ := reader.ReadString('\n')
		if text == "stop\r\n" {
			process = false
		}
	}
}

func task() {
	var i int64 = 0
	for ; i < 10000000000 || process; i++ {
		if i%30000000 == 0 { // Just to slow down an output for a while
			println(i)
		}
	}
}

func main() {
	go task()
	commandHandler()
}

这是我得到的结果。字母是我尝试输入的内容,数字是应用程序的输出结果。

对于如何在我的Go应用程序中实现正确的输入/输出,有什么建议吗?

英文:

What I'm trying to achieve is some kind of an application that logs a lot of information into the console (for instance, numbers from 0 to 1000000000000) and an ability to stop the execution by typing a command in the console (for example "stop").

I came up with an idea of using goroutines, however, I can't type in commands because the input field is changing to output.

Here is my code:

package main

import (
	&quot;bufio&quot;
	&quot;os&quot;
)

var process bool = true

func commandHandler() {
	reader := bufio.NewReader(os.Stdin)
	for process {
		text, _ := reader.ReadString(&#39;\n&#39;)
		if text == &quot;stop\r\n&quot; {
			process = false
		}
	}
}

func task() {
	var i int64 = 0
	for ; i &lt; 10000000000 || process; i++ {
		if i%30000000 == 0 { // Just to slow down an output for a while
			println(i)
		}
	}
}

func main() {
	go task()
	commandHandler()
}

And the result that I get. Letters are my input that I`m trying to type in and numbers - the output of the application

Any suggestions on how to make proper input\output in my Go application?

答案1

得分: 0

我可以很好地输入命令。当你输入命令时,它们会在控制台上显示出来。这些命令会与其他输出内容一起显示在控制台上,这可能会对用户造成困惑,但对计算机来说没有问题。

你的程序运行得很好,只要确保它与你的操作系统匹配:

        if text == "stop\r\n" {

在我的操作系统上,没有\r。一个更通用的方法是使用strings.TrimSpace来去除所有的空白字符。

import (
  ...
  "strings"
) 
... 
...
        if strings.TrimSpace(text) == "stop" {

通过这个改变,代码对我来说可以正常工作。正如你所说,输出和输入会插入到屏幕上,但你仍然可以输入stop来结束程序。

关于如何在Go应用程序中进行正确的输入/输出,几乎没有真实世界的终端程序是交互式的。相反,命令行参数和环境变量通常在程序启动时提供配置。通常使用Shell重定向来保留(写入文件)或分页(例如|less)程序的长时间输出。

你会看到很多学术编程使用交互式终端模型,其中程序提示用户并收集数据,但在现实世界中,这种情况非常罕见,通常是一个不明智的复杂化。标准输入通常用于提供计算所需的数据输入,而不是用户命令(例如,要操作或过滤的数据)。

正如@tinkerer建议的那样,信号已经可以用于终止程序(具体细节取决于操作系统)。所以不需要担心终端应用程序如何处理标准输入和输出的可视化插入以终止程序。在Posix环境中,还有许多其他信号,其中一些完全面向用户,可以用于任意目的。

一旦需要在运行时进行更复杂的用户输入,程序通常会监听一个套接字以接收命令。对于这种类型的程序,使用提供HTTP服务的Web界面变得越来越常见,因为它们简单易用。

英文:

> I can't type in commands because the input field is changing to output

You can type in the commands just fine. They'll be echoed to your console as you type them. This will be combined with everything else that is being output to your console, which can be confusing to the user - but not to the computer.

Your program works just fine, assuming this actually matches on your OS:

        if text == &quot;stop\r\n&quot; {

On my OS there's no \r. A more portable method would be to use strings.TrimSpace to remove all the whitespace.

import (
  ...
  &quot;strings&quot;
) 
... 
...
        if strings.TrimSpace(text) == &quot;stop&quot; {

With this change, the code works for me. As you said, the output and input is interpolated onto the screen, but you can still type stop and end the program.

> Any suggestions on how to make proper input\output in my Go application?

Almost no real world terminal programs are interactive. Instead command line arguments and environment variables provide their configurationat invocation time. Shell redirection is typically used to retain (in a file) or paginate (eg |less) any long output of a program.

You'll see a lot of academic programming using interactive terminal models where the program prompts the user and collects data, but in the real world this is very rare and is generally an ill advised complication. Standard input is typically used to provide data input for computation, rather than user commands (for example, data to be manipulated or filtered).

As @tinkerer suggests, signals can already be used to terminate your program (details are OS specific). So there's really no need to worry about how a terminal application would handle the visual representation of standard input and output being interpolated just to terminate the program. In a Posix environment there are a number of other signals, some of which are entirely user oriented and can be used for arbitrary purposes.

Once more complicated user input is required at runtime, the program typically listens on a socket for commands. For this kind of program, web interfaces serving HTTP have become increasingly common for the simplicity and accessibility.

huangapple
  • 本文由 发表于 2023年1月24日 03:36:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/75214245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定