Golang fmt.Sscanln 函数
最后修改时间 2025 年 5 月 8 日
本教程解释了如何在 Go 中使用 fmt.Sscanln 函数。我们将通过解析格式化字符串的实际示例来涵盖字符串扫描基础知识。
fmt.Sscanln 函数从字符串中扫描以空格分隔的值。它在换行符处停止扫描,并要求输入以换行符或 EOF 结尾。它返回成功扫描的项目数。
在 Go 中,fmt.Sscanln 类似于 fmt.Scanln,但它从字符串而不是标准输入读取。它对于将结构化字符串数据解析到变量中很有用。
基本字符串扫描示例
fmt.Sscanln 最简单的用法是从字符串解析基本值。此示例演示了扫描整数和字符串。
注意:输入字符串必须与预期格式完全匹配。
package main
import (
"fmt"
)
func main() {
var name string
var age int
input := "John 25\n"
n, err := fmt.Sscanln(input, &name, &age)
if err != nil {
fmt.Println("Error scanning:", err)
return
}
fmt.Printf("Scanned %d items: %s is %d years old\n", n, name, age)
}
该函数从输入字符串扫描两个值。它返回成功扫描的项目数以及扫描过程中发生的任何错误。
扫描多个值
fmt.Sscanln 可以一次解析多种不同类型的值。此示例展示了从字符串扫描混合数据类型。
package main
import (
"fmt"
)
func main() {
var product string
var price float64
var inStock bool
input := "Laptop 1299.99 true\n"
n, err := fmt.Sscanln(input, &product, &price, &inStock)
if err != nil {
fmt.Println("Error scanning:", err)
return
}
fmt.Printf("Scanned %d items: %s costs $%.2f (in stock: %t)\n",
n, product, price, inStock)
}
该示例从输入中扫描字符串、浮点数和布尔值。该函数在可能的情况下会自动将值转换为目标变量类型。
处理扫描错误
扫描不可预测的输入时,错误处理很重要。此示例演示了使用 fmt.Sscanln 进行的正确错误处理。
package main
import (
"fmt"
)
func main() {
var x, y int
tests := []string{
"10 20\n",
"10 abc\n",
"10\n",
}
for _, input := range tests {
n, err := fmt.Sscanln(input, &x, &y)
if err != nil {
fmt.Printf("Input: %q Error: %v (scanned %d items)\n",
input, err, n)
continue
}
fmt.Printf("Scanned successfully: x=%d y=%d\n", x, y)
}
}
该代码测试了不同的输入场景并适当地处理了错误。请注意,在发生错误时,它如何报告部分扫描结果。
使用指针进行扫描
fmt.Sscanln 需要指向变量的指针来存储扫描的值。此示例显示了正确的指针用法和要避免的常见错误。
package main
import (
"fmt"
)
func main() {
var a int
var b float64
var c string
// Correct way: passing pointers
input1 := "42 3.14 hello\n"
n1, err1 := fmt.Sscanln(input1, &a, &b, &c)
if err1 != nil {
fmt.Println("Error:", err1)
} else {
fmt.Printf("Scanned %d values: %d, %.2f, %q\n", n1, a, b, c)
}
// Incorrect way: passing values (will not compile)
// n2, err2 := fmt.Sscanln(input1, a, b, c)
}
该示例对比了正确的指针用法和错误的值传递。请记住,所有目标变量都必须作为指针传递。
扫描到结构体字段
我们可以直接使用指针扫描到结构体字段中。此示例演示了使用 fmt.Sscanln 进行的结构化数据解析。
package main
import (
"fmt"
)
type Person struct {
Name string
Age int
City string
}
func main() {
var p Person
input := "Alice 30 NewYork\n"
n, err := fmt.Sscanln(input, &p.Name, &p.Age, &p.City)
if err != nil {
fmt.Println("Error scanning:", err)
return
}
fmt.Printf("Scanned %d fields: %+v\n", n, p)
}
该代码直接将值扫描到结构体的字段中。这种模式对于将字符串数据转换为 Go 的结构化类型非常有用。
自定义类型扫描
fmt.Sscanln 可与实现 Scanner 接口的自定义类型一起使用。此示例展示了如何为自定义类型启用扫描。
package main
import (
"fmt"
"strings"
)
type RGB struct {
R, G, B int
}
func (c *RGB) Scan(f fmt.ScanState, verb rune) error {
_, err := fmt.Fscanf(f, "%d,%d,%d", &c.R, &c.G, &c.B)
return err
}
func main() {
var color RGB
input := "255,128,0\n"
_, err := fmt.Sscanln(input, &color)
if err != nil {
fmt.Println("Error scanning color:", err)
return
}
fmt.Printf("Scanned color: R=%d G=%d B=%d\n", color.R, color.G, color.B)
}
RGB 类型实现了 Scanner 接口。这使得 fmt.Sscanln 能够解析自定义格式的数据。
扫描可变长度的输入
我们可以使用扫描来处理具有不同数量值的输入。此示例展示了使用 fmt.Sscanln 进行的灵活输入解析。
package main
import (
"fmt"
)
func main() {
inputs := []string{
"100\n",
"100 200\n",
"100 200 300\n",
}
for _, input := range inputs {
var a, b, c int
n, err := fmt.Sscanln(input, &a, &b, &c)
if err != nil && n < 3 {
fmt.Printf("Input: %q Scanned %d values: a=%d b=%d c=%d\n",
input, n, a, b, c)
continue
}
fmt.Printf("Fully scanned: a=%d b=%d c=%d\n", a, b, c)
}
}
该代码处理具有不同数量值的输入。当输入不包含所有预期值时,它会报告部分扫描结果。
来源
本教程通过字符串解析和扫描技术的实际示例,涵盖了 Go 中的 fmt.Sscanln 函数。