我正在尝试学习Go,但坚持使用这个:http://ideone.com/hbCamr或http://ideone.com/OvRw7t
package main
import "fmt"
func main(){
var i int
var f float64
var s string
_, err := fmt.Scan(&i)
if err == nil {
fmt.Println("read 1 integer: ",i)
} else {
fmt.Println("Error: ",err)
}
_, err = fmt.Scan(&f)
if err == nil {
fmt.Println("read 1 float64: ",f)
} else {
fmt.Println("Error: ",err)
}
_, err = fmt.Scan(&s)
if err == nil {
fmt.Println("read 1 string: ",s)
} else {
fmt.Println("Error: ",err)
}
_, err = fmt.Scanln(&s)
if err == nil {
fmt.Println("read 1 line: ",s)
} else {
fmt.Println("Error: ",err)
}
}
输入:
123
123.456
everybody loves ice cream
输出是:
read 1 integer: 123
read 1 float64: 123.456
read 1 string: everybody
Error: Scan: expected newline
这是预期的行为吗?为什么它不像C ++ getline那样工作? http://ideone.com/Wx8z5o
答案 0 :(得分:6)
Scanln与“扫描”类似,但在换行符处停止扫描,在最终项目之后必须有换行符或EOF。
Scan
的行为也是documented:
扫描扫描从标准输入读取的文本,将连续的空格分隔值存储到连续的参数中。换行计为空格。它返回成功扫描的项目数。如果这小于参数的数量,则错误将报告原因。
总结:Scan
将每个单词(由空格分隔的字符串)放入相应的参数中,将换行视为空格。 Scanln
执行相同操作,但将换行符视为停止字符,而不是在此之后进一步解析。
如果您想阅读一行(最后为\n
),请使用bufio.Reader
及其ReadString
方法:
line, err := buffer.ReadString('\n')
答案 1 :(得分:1)
作为一种解决方法,您可以实现自己的 fmt.Scanner
:
package main
import "fmt"
type newline struct { tok string }
func (n *newline) Scan(state fmt.ScanState, verb rune) error {
tok, err := state.Token(false, func(r rune) bool {
return r != '\n'
})
if err != nil {
return err
}
if _, _, err := state.ReadRune(); err != nil {
if len(tok) == 0 {
panic(err)
}
}
n.tok = string(tok)
return nil
}
func main() {
var n newline
fmt.Scan(&n)
fmt.Println(n.tok)
}