这看起来几乎是正确的,但它在换行线上窒息。 最好的方法是什么?
package main
import (
"fmt"
"strings"
)
func main() {
var z float64
var a []float64
// \n gives an error for Fscanf
s := "3.25 -12.6 33.7 \n 3.47"
in := strings.NewReader(s)
for {
n, err := fmt.Fscanf(in, "%f", &z)
fmt.Println("n", n)
if err != nil {
break
}
a = append(a, z)
}
fmt.Println(a)
}
输出:
n 1
n 1
n 1
n 0
[3.25 -12.6 33.7]
更新
请参阅下面@Atom的答案。我找到了另一种方法,如果错误是EOF就会中断,否则只是忽略它。我知道,这只是一个黑客,但我控制了源。
_, err := fmt.Fscanf(in, "%f", &z)
if err == os.EOF { break }
if err != nil { continue }
答案 0 :(得分:5)
如果您只解析花车,可以使用fmt.Fscan(r io.Reader, a ...interface{})
代替fmt.Fscanf(r io.Reader, format string, a ...interface{})
:
var z float64
...
n, err := fmt.Fscan(in, &z)
fmt.Fscan
和fmt.Fscanf
之间的区别在于fmt.Fscan
新行计为空格。后一个函数(带有格式字符串)不会将换行视为空格,并且需要输入中的换行符以匹配格式字符串中的换行符。
带有格式字符串的函数可以更好地控制输入形式,例如当您需要扫描%5f
或%10s
时。在这种情况下,如果输入包含换行符并且它实现了接口io.RuneScanner
,则可以使用方法ReadRune
查看下一个字符,如果不是,则可以选择将其与UnreadRune
一起读取空格或换行符。
答案 1 :(得分:2)
如果你的输入只是一串行,每行都有一个由空格分隔的浮点数,那么从文件中一次读取一行可能更容易,在该行上运行Sscanf(假设浮点数为on)每条线都是固定的)。但是这里有一些适用于你的例子 - 可能有一种方法可以提高效率。
package main
import (
"fmt"
"strings"
)
func main() {
var z float64
var a []float64
// \n gives an error for Fscanf
s := "3.25 -12.6 33.7 \n 3.47"
for _, line := range strings.Split(s, "\n") {
in := strings.NewReader(line)
for {
n, err := fmt.Fscanf(in, "%f", &z)
fmt.Println("n", n)
if err != nil {
fmt.Printf("ERROR: %v\n", err)
break
}
a = append(a, z)
}
}
fmt.Println(a)
}