是否可以将`fmt.Fscan`或`fmt.Scan`用于标准I / O?

时间:2018-03-27 15:53:52

标签: go io

关于Golang中的标准I \ O,网上的所有教程,无一例外地讨论和使用我测试过的bufio并且工作正常。

但我的问题是关于使用fmt包来读取标准输入,这会导致错误或陷入循环。 根据{{​​1}}文档:

  

扫描扫描从标准输入读取的文本,连续存储   空格分隔的值到连续的参数中。换行计为   空间。它返回成功扫描的项目数。如果那样的话   小于参数的数量,错误将报告原因。

在第一句中,据说fmt.Scan从标准输入中读取,但它根本不起作用! 也适用于具有此签名的Scan

fmt.Fscan

当我输入一个单词时,它会抛出异常,我甚至无法理解它们!

那么,是否可以使用这两种方法来读取标准输入?

有关详细信息,这是我的代码:

func Fscan(r io.Reader, a ...interface{}) (n int, err error)

}

编辑:输入上述代码中的单词时出现的错误:

package main

import (
    "fmt"
    "os"
)

func main() {

    fmt.Print("pls enter name: ")

    var st *string

    n, err := fmt.Fscan(os.Stdin, st)

    fmt.Println(st)

    fmt.Println(n)
    fmt.Println(err)

2 个答案:

答案 0 :(得分:4)

我注意到您的代码首先注意的是您将nil指针传递给fmt.Fscan,即您将变量st声明为*string,但地址是尚不存在。应写成:

var st string
_, err := fmt.Fscan(os.Stdin, &st)
if err != nil {
    fmt.Println(err)
} 

在我的修订示例中,st现在有一个内存地址(string的零值为""),因此可以使用&获取其地址然后转到fmt.Fscan。其次,您应该注意我如何处理从err返回的fmt.Fscan - 您只需打印err,但如果未返回error该怎么办?然后errnil并且您的fmt.Println(err)无缘无故地执行 - 有条件地处理返回的error,这与上面的示例相同。

然而,更常见的是使用fmt.Scanf,如此:

var st string
fmt.Scanf("%s", &st)

阅读文档以获取更多信息。 The "fmt" package

答案 1 :(得分:2)

指向string的指针是不必要的,您只需提供对初始化字符串的引用。

package main

import (
    "fmt"
    "os"
)

func main() {

    fmt.Print("pls enter name: ")

    var str string

    size,err := fmt.Fscan(os.Stdin, &str)

    if err != nil{
        fmt.Println("Error reading name",err)
    }

    fmt.Printf("Number of fields: %d. Text: %s",size,str)

}

您会注意到可以解析多个字段:

func main() {

    fmt.Print("Please enter your first and last name seperated by a space")

    var firstName string
    var lastName string

    size,err := fmt.Fscan(os.Stdin, &firstName, &lastName)

    //...
}