Go 要使用哪个扫描从字符串读取浮动?

Go 要使用哪个扫描从字符串读取浮动?,go,Go,这似乎几乎是正确的,但它扼杀了新线。 最好的方法是什么 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 {

这似乎几乎是正确的,但它扼杀了新线。 最好的方法是什么

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 }

如果您的输入只是一组行,每行上都有空格分隔的浮点数,那么一次只读取文件中的一行可能会更容易,在该行上运行Sscanf(假设每行上的浮点数是固定的)。但在你的例子中,有一点是有效的——也许有一种方法可以使它更有效

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)
}

如果您的输入只是一组行,每行上都有空格分隔的浮点数,那么一次只读取文件中的一行可能会更容易,在该行上运行Sscanf(假设每行上的浮点数是固定的)。但在你的例子中,有一点是有效的——也许有一种方法可以使它更有效

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)
}

如果您仅解析浮点,则可以使用
fmt.Fscan(r io.Reader,a…interface{})
而不是
fmt.Fscanf(r io.Reader,format string,a…interface{})

fmt.Fscan
fmt.Fscanf
之间的区别在于,在
fmt.Fscan
的情况下,换行符算作空格。后一个函数(带有格式字符串)不将换行符视为空格,并要求输入中的换行符与格式字符串中的换行符匹配


带有格式字符串的函数可以更好地控制输入形式,例如当您需要扫描
%5f
%10s
时。在这种情况下,如果输入包含换行符,并且它实现了接口,那么您可以使用
ReadRune
方法查看下一个字符,如果不是空格或换行符,还可以选择使用
UnreadRune
未读它。

如果您只解析浮点数,您可以使用
fmt.Fscan(r io.Reader,a…interface{})
而不是
fmt.Fscanf(io.Reader,格式字符串,一个…接口{})

fmt.Fscan
fmt.Fscanf
之间的区别在于,在
fmt.Fscan
的情况下,换行符算作空格。后一个函数(带有格式字符串)不将换行符视为空格,并要求输入中的换行符与格式字符串中的换行符匹配


带有格式字符串的函数可以更好地控制输入形式,例如当您需要扫描
%5f
%10s
时。在这种情况下,如果输入包含换行符并实现了接口,则可以使用方法
ReadRune
查看下一个字符,如果不是空格或换行符,还可以选择使用
UnreadRune
未读。

谢谢。我知道我可以先分手。希望能有更深入的了解。同时,我可以通过执行“if err==os.EOF{break}”然后执行“if err!=nil{continue}”来实现它,但这看起来像是一个黑客程序。不确定哪个错误对应“意外换行符”。谢谢。我知道我可以先分手。希望能有更深入的了解。同时,我可以通过执行“if err==os.EOF{break}”然后执行“if err!=nil{continue}”来实现它,但这看起来像是一个黑客程序。不确定哪个错误对应“意外换行符”。这很尴尬。我在文档中看到了这个函数,但不知道如何使用…接口{}。然后我找到了一个要复制的示例,它以Fscanf和&z作为参数,我不想回到Fscan。然而,我仍然不知道这个函数签名是什么意思。还没有找到任何解释。包
fmt
的文档正在解释
a…interface{}
,其中有一句话:“所有要扫描的参数必须是指向扫描器接口的基本类型或实现的指针”。这很尴尬。我在文档中看到了这个函数,但不知道如何使用…接口{}。然后我找到了一个要复制的示例,它以Fscanf和&z作为参数,我不想回到Fscan。然而,我仍然不知道这个函数签名是什么意思。尚未找到任何解释。包
fmt
的文档用以下句子解释
a…interface{}
:“要扫描的所有参数必须是指向扫描器接口的基本类型或实现的指针”。