Golang 从标准输入行读取多个字段

Golang reading multiple fields from stdin line

$ echo "A 1 2 3 4" | go run test.go 
entire:  A
next field:  A

我需要从标准输入中读取几行,例如 "A 1 2 3 4"(代码现在只有一行),但出现了问题。 Scanln 应该读整行而 Fields 应该用换行符分开吗?为什么Scanln只读一个字?

package main

import (
    "fmt"
    "strings"
)

func main() {
    var line string
    fmt.Scanln(&line)
    fmt.Println("entire: ",line)
    for _,x := range strings.Fields(line) {
        fmt.Println("next field: ",x)
    }
}

$ echo "A 1 2 3 4" | go run test.go 
entire:  A
next field:  A

我被另一个问题的答案误导了,那个问题说 Scanln 读了一整行。不,Scanln 只是一个 Scan,它读取单词(space 分隔的字符串)和指定的实际变量数量,但在换行时退出解析。它完全混淆了 Go 中的 readline 等价物。

你试过了吗:

package main

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

func main() {
    var line string
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        line = scanner.Text()
        fmt.Println("Got line:", line)
        for _, x := range strings.Fields(line) {
            fmt.Println("next field: ",x)
        }
    }
}

然后:

$ printf "aa bb \n cc dd " | go run 1.go  
Got line: aa bb
next field:  aa
next field:  bb
Got line:  cc dd
next field:  cc
next field:  dd

如果您想将每个输入存储到一个单独的变量中,您可以试试这个:

package main

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

func main() {
    var a, b string
    var c int
    var r = bufio.NewReader(os.Stdin)
    fmt.Fscanf(r, "%s %s %d", &a, &b, &c)
    fmt.Printf("%s %s %d", a, b, c)
}

它将给出以下输出:

//given input
w r 4
//output
w r 4

我意识到这是一个老问题,但我一直在寻找同样的东西,并意识到我们可以改进解释。

其实是发帖人@ArekBulski的评论给了我线索

Scanln is only a Scan that reads words (space separated strings) and as many as actual variables specified

Scanln() 将读取整行,但它只保存与参数中变量数量相等的字符串数,因此对于“A 1 2 3 4”fmt.Scanln(&var1) 将仅存储“A " 和 fmt.Scanln(&var1, &var2) 只会将 "A" 和 "1" 分别存储在 var1 和 var2 中。

因此,当您知道进入的变量数量时,fmt.Scanln(a ...interface{}) 很合适,否则 bufio.NewScanner(os.Stdin) 可能更合适。