dqrmkdu25623
2018-03-27 15:53 阅读 63
已采纳

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

About the standard I\O in Golang, all tutorial on the net, Without exception, discuss and use bufio which I tested and worked fine.

But my question is about using fmt package for reading standard input which either gives me errors or trapped in a loop. According to the fmt.Scan documentation:

Scan scans text read from standard input, storing successive space-separated values into successive arguments. Newlines count as space. It returns the number of items successfully scanned. If that is less than the number of arguments, err will report why.

In the first sentence it is said that Scan reads from standard input, but it doesn't work at all! also for fmt.Fscan which have this signature:

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

when I enter a word, it throws exceptions and I can't even understand them!

So, is it possible to use these 2 methods to read standard input?


for more information this is my code:

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)

}

EDIT: the error I get when entering a word in above code:

panic: runtime error: invalid memory address or nil pointer dereference [recover
ed]
        panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x8 pc=0x4977aa]

goroutine 1 [running]:
fmt.errorHandler(0xc04206be40)
        C:/development/Programming Languages/GO/src/fmt/scan.go:1031 +0x14f
panic(0x4b15a0, 0x544720)
        C:/development/Programming Languages/GO/src/runtime/panic.go:505 +0x237
fmt.(*ss).scanOne(0xc042044060, 0x76, 0x4a6460, 0x0)
        C:/development/Programming Languages/GO/src/fmt/scan.go:979 +0xc7a
fmt.(*ss).doScan(0xc042044060, 0xc04206bf48, 0x1, 0x1, 0x0, 0x0, 0x0)
        C:/development/Programming Languages/GO/src/fmt/scan.go:1040 +0x9d
fmt.Fscan(0x4de080, 0xc042004010, 0xc04206bf48, 0x1, 0x1, 0x0, 0x10, 0x4b36c0)
        C:/development/Programming Languages/GO/src/fmt/scan.go:123 +0xd2
main.main()
        C:/Users/Hamed/Documents/Go Projects/src/golang/learning/helloworld/firs
tApp.go:22 +0xe3
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    duanming0494 duanming0494 2018-03-27 16:06

    The first thing I notice with your code is that you're passing a nil pointer to fmt.Fscan, i.e. you declare the variable st as *string but the address does not yet exist. It should be written:

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

    In my revised example, st now has a memory address (a string's zero value is ""), so it's address can be obtained using & and then passed to fmt.Fscan. Second, you should note how I handle err returned from fmt.Fscan - you simply print err, but what if an error is not returned? Then err is nil and your fmt.Println(err) is executed for no reason - it is idiomatic to handle returned errors conditionally, as is done in the above example.

    However it is more common to use fmt.Scanf like so:

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

    Read the docs for more information. The "fmt" package.

    点赞 评论 复制链接分享
  • dongyi1441 dongyi1441 2018-03-27 16:05

    A pointer to a string is unnecessary, you simply need to provide a reference to an initialised 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)
    
    }
    

    You'll notice that multiple fields can be parsed:

    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)
    
        //...
    }
    
    点赞 评论 复制链接分享

相关推荐