【问题标题】:Golang reading multiple fields from stdin lineGolang 从标准输入行读取多个字段
【发布时间】:2017-09-07 02:16:41
【问题描述】:
$ 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

【问题讨论】:

    标签: go split scanf stdin


    【解决方案1】:

    你试过了吗:

    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
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案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
        

        【讨论】:

          【解决方案4】:

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

          原来发帖者@ArekBulski 的评论给了我线索

          Scanln 只是读取单词(空格分隔的字符串)和指定的实际变量的 Scan

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

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

          【讨论】:

            猜你喜欢
            • 2018-02-05
            • 1970-01-01
            • 2015-07-24
            • 2016-12-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多