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

3
$ 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
4个回答

6
你尝试过以下方法吗:
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

3

如果您想将每个输入存储到单独的变量中,可以尝试以下方法:

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

2
我被另一个问题的答案误导了,它说Scanln会读取整行。不,Scanln只是一个扫描器,它读取单词(以空格分隔的字符串),并且只读取指定数量的变量,但在遇到换行符时停止解析。在Go中,相当于readline的等效方法非常混乱。

1

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

实际上,原始发布者@ArekBulskithat的评论给了我线索,他说

Scanln只是读取单词(以空格分隔的字符串)并且与指定的实际变量一样多

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

因此,fmt.Scanln(a ...interface{})是一个很好的选择,当您知道要输入的变量数量时,否则bufio.NewScanner(os.Stdin)可能更适合。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接