How can I read from standard input in the console?

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

How can I read from standard input in the console?

问题

我想从命令行读取标准输入,但是我的尝试都以程序在我被提示输入之前退出。我正在寻找在C#中等效的Console.ReadLine()

这是我目前的代码:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("输入文本:")
    text, _ := reader.ReadString('\n')
    fmt.Println(text)

    fmt.Println("输入文本:")
    text2 := ""
    fmt.Scanln(&text2)
    fmt.Println(text2)

    ln := ""
    fmt.Sscanln("%v", &ln)
    fmt.Println(ln)
}
英文:

I would like to read standard input from the command line, but my attempts have ended with the program exiting before I'm prompted for input. I'm looking for the equivalent of Console.ReadLine() in C#.

This is what I currently have:

package main

import (
    "bufio"
    "fmt"
    "os"
)

func main() {
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Enter text: ")
    text, _ := reader.ReadString('\n')
    fmt.Println(text)

    fmt.Println("Enter text: ")
    text2 := ""
    fmt.Scanln(text2)
    fmt.Println(text2)

    ln := ""
    fmt.Sscanln("%v", ln)
    fmt.Println(ln)
}

答案1

得分: 411

我不确定块中出了什么问题。

reader := bufio.NewReader(os.Stdin)
fmt.Print("输入文本:")
text, _ := reader.ReadString('\n')
fmt.Println(text)

在我的机器上它是可以工作的。然而,对于下一个块,你需要一个指向你分配输入的变量的指针。尝试用fmt.Scanln(&text2)替换fmt.Scanln(text2)。不要使用Sscanln,因为它解析的是已经在内存中的字符串,而不是从标准输入中读取。如果你想做类似你尝试做的事情,可以用fmt.Scanf("%s", &ln)替换它。

如果这仍然不起作用,你的问题可能是一些奇怪的系统设置或者一个有问题的IDE。

英文:

I'm not sure what's wrong with the block

reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
fmt.Println(text)

As it works on my machine. However, for the next block you need a pointer to the variables you're assigning the input to. Try replacing fmt.Scanln(text2) with fmt.Scanln(&text2). Don't use Sscanln, because it parses a string already in memory instead of from stdin. If you want to do something like what you were trying to do, replace it with fmt.Scanf("%s", &ln)

If this still doesn't work, your culprit might be some weird system settings or a buggy IDE.

答案2

得分: 166

你可以尝试以下代码:

scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

if scanner.Err() != nil {
    // 处理错误。
}
英文:

You can as well try:

scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
    fmt.Println(scanner.Text())
}

if scanner.Err() != nil {
    // Handle error.
}

答案3

得分: 129

我认为一个更标准的方法是:

package main

import "fmt"

func main() {
    fmt.Print("输入文本:")
    var input string
    fmt.Scanln(&input)
    fmt.Print(input)
}

可以查看 scan 的 godoc:http://godoc.org/fmt#Scan

Scan 从标准输入中扫描文本,将连续的以空格分隔的值存储到连续的参数中。换行符被视为空格。

Scanln 类似于 Scan,但在换行符处停止扫描,并且在最后一项之后必须有一个换行符或 EOF。

英文:

I think a more standard way to do this would be:

package main

import "fmt"

func main() {
    fmt.Print("Enter text: ")
    var input string
    fmt.Scanln(&input)
    fmt.Print(input)
}

Take a look at the scan godoc: http://godoc.org/fmt#Scan

> Scan scans text read from standard input, storing successive space-separated values into successive arguments. Newlines count as space.
>
> Scanln is similar to Scan, but stops scanning at a newline and after the final item there must be a newline or EOF.

答案4

得分: 79

始终尝试使用bufio.NewScanner从控制台获取输入。正如其他人提到的,有多种方法可以完成这个任务,但Scanner最初就是用来完成这个任务的。Dave Cheney解释了为什么你应该使用Scanner而不是bufio.Reader的ReadLine。

以下是你问题的代码片段答案:

package main

import (
    "bufio"
    "fmt"
    "os"
)

/*
 Three ways of taking input
   1. fmt.Scanln(&input)
   2. reader.ReadString()
   3. scanner.Scan()

   Here we recommend using bufio.NewScanner
*/

func main() {
    // To create dynamic array
    arr := make([]string, 0)
    scanner := bufio.NewScanner(os.Stdin)
    for {
        fmt.Print("Enter Text: ")
        // Scans a line from Stdin(Console)
        scanner.Scan()
        // Holds the string that scanned
        text := scanner.Text()
        if len(text) != 0 {
            fmt.Println(text)
            arr = append(arr, text)
        } else {
            break
        }

    }
    // Use collected inputs
    fmt.Println(arr)
}

如果你不想以编程方式收集输入只需添加以下代码

   scanner := bufio.NewScanner(os.Stdin)
   scanner.Scan()
   text := scanner.Text()
   fmt.Println(text)

以上程序的输出将是

Enter Text: Bob
Bob
Enter Text: Alice
Alice
Enter Text:
[Bob Alice]

以上程序收集用户输入并将其保存到一个数组中我们还可以使用特殊字符来中断该流程Scanner提供了用于高级用法的API例如使用自定义函数进行拆分扫描不同类型的I/O流标准的`Stdin``String`

编辑原帖中链接的推文无法访问但是可以在这个标准库文档中找到使用Scanner的官方参考https://pkg.go.dev/bufio@go1.17.6#example-Scanner-Lines

<details>
<summary>英文:</summary>

Always try to use the **bufio.NewScanner** for collecting input from the console. As others mentioned, there are multiple ways to do the job, but Scanner is originally intended to do the job. Dave Cheney explains why you should use Scanner instead of bufio.Reader&#39;s ReadLine.

 https://twitter.com/davecheney/status/604837853344989184?lang=en

Here is the code snippet answer for your question

    package main

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

    /*
     Three ways of taking input
       1. fmt.Scanln(&amp;input)
       2. reader.ReadString()
       3. scanner.Scan()

       Here we recommend using bufio.NewScanner
    */

    func main() {
        // To create dynamic array
        arr := make([]string, 0)
        scanner := bufio.NewScanner(os.Stdin)
        for {
            fmt.Print(&quot;Enter Text: &quot;)
            // Scans a line from Stdin(Console)
            scanner.Scan()
            // Holds the string that scanned
            text := scanner.Text()
            if len(text) != 0 {
                fmt.Println(text)
                arr = append(arr, text)
            } else {
                break
            }

        }
        // Use collected inputs
        fmt.Println(arr)
    }

If you don&#39;t want to programmatically collect the inputs, just add these lines

       scanner := bufio.NewScanner(os.Stdin)
       scanner.Scan()
       text := scanner.Text()
       fmt.Println(text)

The output of above program will be:

    Enter Text: Bob
    Bob
    Enter Text: Alice
    Alice
    Enter Text:
    [Bob Alice]

The above program collects the user input and saves them to an array. We can also break that flow with a special character. Scanner provides API for advanced usage like splitting using a custom function, etc., scanning different types of I/O streams (standard `Stdin`, `String`), etc.

Edit: The tweet linked in original post is not accesible. But, one can find official reference of using Scanner from this standard library documentation: https://pkg.go.dev/bufio@go1.17.6#example-Scanner-Lines




</details>



# 答案5
**得分**: 16

在循环中读取多个带有空格的输入的另一种方法

```go
package main
import (
    "fmt"
    "bufio"
    "os"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    var text string
    for text != "q" {  // 如果text == "q",则跳出循环
        fmt.Print("请输入文本:")
        scanner.Scan()
        text = scanner.Text()
        if text != "q" {
            fmt.Println("您输入的文本是:", text)
        }
    }
}

输出:

请输入文本:Hello world!
您输入的文本是: Hello world!
请输入文本:Go is awesome!
您输入的文本是: Go is awesome!
请输入文本:q
英文:

Another way to read multiple inputs within a loop which can handle an input with spaces:

package main
import (
&quot;fmt&quot;
&quot;bufio&quot;
&quot;os&quot;
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
var text string
for text != &quot;q&quot; {  // break the loop if text == &quot;q&quot;
fmt.Print(&quot;Enter your text: &quot;)
scanner.Scan()
text = scanner.Text()
if text != &quot;q&quot; {
fmt.Println(&quot;Your text was: &quot;, text)
}
}
}

Output:

Enter your text: Hello world!
Your text was:  Hello world!
Enter your text: Go is awesome!
Your text was:  Go is awesome!
Enter your text: q

答案6

得分: 11

可以这样做:

package main
import "fmt"
func main(){
var myname string
fmt.Scanf("%s", &myname)
fmt.Println("你好", myname)
}
英文:

It can also be done like this:

package main
import &quot;fmt&quot;
func main(){
var myname string
fmt.Scanf(&quot;%s&quot;, &amp;myname)
fmt.Println(&quot;Hello&quot;, myname)
}

答案7

得分: 9

我迟到了。但是这个一行代码怎么样:

data, err := io.ReadAll(os.Stdin)

完成后按下ctrl+d。

英文:

I'm late to the party. But how about one liner:

data, err := io.ReadAll(os.Stdin)

And press ctrl+d once done.

答案8

得分: 5

干净地读取几个提示的值:

// 创建一个可以多次调用的单个读取器
reader := bufio.NewReader(os.Stdin)
// 提示并读取
fmt.Print("输入文本:")
text, _ := reader.ReadString('\n')
fmt.Print("输入更多文本:")
text2, _ := reader.ReadString('\n')
// 去除空格并打印
fmt.Printf("文本1: "%s", 文本2: "%s"\n",
strings.TrimSpace(text), strings.TrimSpace(text2))

这是一个运行示例:

输入文本:Jim
输入更多文本:Susie
文本1: "Jim", 文本2: "Susie"

英文:

Cleanly read in a couple of prompted values:

// Create a single reader which can be called multiple times
reader := bufio.NewReader(os.Stdin)
// Prompt and read
fmt.Print(&quot;Enter text: &quot;)
text, _ := reader.ReadString(&#39;\n&#39;)
fmt.Print(&quot;Enter More text: &quot;)
text2, _ := reader.ReadString(&#39;\n&#39;)
// Trim whitespace and print
fmt.Printf(&quot;Text1: \&quot;%s\&quot;, Text2: \&quot;%s\&quot;\n&quot;,
strings.TrimSpace(text), strings.TrimSpace(text2))

Here's a run:

Enter text: Jim
Enter More text: Susie
Text1: &quot;Jim&quot;, Text2: &quot;Susie&quot;

答案9

得分: 5

请尝试以下代码:

var input string
func main() {
    fmt.Print("请输入您的姓名=")
    fmt.Scanf("%s", &input)
    fmt.Println("你好," + input)
}

这段代码是一个简单的Go语言程序,它会提示用户输入姓名,并输出"你好,"加上用户输入的姓名。

英文:

Try this code:

var input string
func main() {
fmt.Print(&quot;Enter Your Name=&quot;)
fmt.Scanf(&quot;%s&quot;, &amp;input)
fmt.Println(&quot;Hello &quot; + input)
}

答案10

得分: 5

你需要提供一个指向你想要扫描的变量的指针,像这样:

fmt.scan(&text2)
英文:

You need to provide a pointer to the variable you want to scan, like so:

fmt.scan(&amp;text2)

答案11

得分: 3

在我的情况下,程序没有等待是因为我使用了watcher命令来自动运行程序。手动运行程序go run main.go会显示"Enter text",然后最终在控制台上打印出输入的文本。

fmt.Print("Enter text: ")
var input string
fmt.Scanln(&input)
fmt.Print(input)
英文:

In my case, the program was not waiting because I was using the watcher command to auto run the program. Manually running the program go run main.go resulted in "Enter text" and eventually printing to the console.

fmt.Print(&quot;Enter text: &quot;)
var input string
fmt.Scanln(&amp;input)
fmt.Print(input)

答案12

得分: 0

让我们简单地完成它

s := ""
b := make([]byte, 1)
for os.Stdin.Read(b); b[0] != '\n'; os.Stdin.Read(b) {
s += string(b)
}
fmt.Println(s)
英文:

Let's do it very simple

s:=&quot;&quot;
b := make([]byte, 1)
for os.Stdin.Read(b) ; b[0]!=&#39;\n&#39;; os.Stdin.Read(b) {
s+=string(b)
}
fmt.Println(s)

huangapple
  • 本文由 发表于 2014年1月3日 10:33:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/20895552.html
匿名

发表评论

匿名网友

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

确定