Golang fmt.Sscan 函数
最后修改时间 2025 年 5 月 8 日
本教程解释了如何在 Go 中使用 fmt.Sscan
函数。我们将通过格式化输入的实际示例来涵盖字符串解析基础知识。
fmt.Sscan
函数扫描一个字符串并将连续的空格分隔值存储到参数中。它返回成功扫描的项目数和遇到的任何错误。
在 Go 中,fmt.Sscan
对于将简单的字符串数据解析到变量中非常有用。它是 fmt 包的一部分,该包处理格式化 I/O 操作。
基本的 fmt.Sscan 示例
fmt.Sscan
最简单的用法是从字符串解析空格分隔的值。此示例演示了基本的字符串扫描。
注意:输入字符串中的值必须用空格分隔。
package main import ( "fmt" ) func main() { var name string var age int input := "John 42" n, err := fmt.Sscan(input, &name, &age) if err != nil { fmt.Println("Error scanning:", err) return } fmt.Printf("Scanned %d values: %s is %d years old\n", n, name, age) }
代码将输入字符串中的两个值扫描到变量中。该函数返回成功扫描的项目数和任何错误。
扫描多个值
fmt.Sscan
可以从字符串解析不同类型的多个值。此示例显示了扫描各种数据类型。
package main import ( "fmt" ) func main() { var ( name string age int height float64 active bool ) input := "Alice 25 1.68 true" n, err := fmt.Sscan(input, &name, &age, &height, &active) if err != nil { fmt.Println("Error scanning:", err) return } fmt.Printf("Scanned %d values:\n", n) fmt.Printf("Name: %s\nAge: %d\nHeight: %.2f\nActive: %t\n", name, age, height, active) }
该示例从单个字符串扫描字符串、整数、浮点数和布尔值。每个值都必须与变量中预期的类型匹配。
处理扫描错误
当输入与预期类型不匹配时,fmt.Sscan
会返回错误。此示例演示了错误处理。
package main import ( "fmt" ) func main() { var count int var price float64 inputs := []string{ "5 9.99", // valid "five 9.99", // invalid "5 nine", // invalid } for _, input := range inputs { n, err := fmt.Sscan(input, &count, &price) if err != nil { fmt.Printf("Error scanning '%s': %v\n", input, err) continue } fmt.Printf("Scanned %d items from '%s': %d, %.2f\n", n, input, count, price) } }
代码尝试扫描不同的输入字符串。无效输入会产生错误,我们在程序中对其进行优雅处理。
扫描到结构体
我们可以使用 fmt.Sscan
从字符串填充结构体字段。此示例显示了结构化数据解析。
package main import ( "fmt" ) type Person struct { Name string Age int City string } func main() { var p Person input := "Bob 35 NewYork" n, err := fmt.Sscan(input, &p.Name, &p.Age, &p.City) if err != nil { fmt.Println("Error scanning:", err) return } fmt.Printf("Scanned %d fields into struct:\n%+v\n", n, p) }
该示例将值直接扫描到结构体的字段中。结构体必须具有导出的字段(大写名称)才能访问。
将 Sscan 与可变参数一起使用
我们可以使用 fmt.Sscan
的可变参数来创建灵活的扫描函数。此示例展示了一个可重用的扫描函数。
package main import ( "fmt" ) func scanValues(input string, values ...interface{}) error { n, err := fmt.Sscan(input, values...) if err != nil { return err } if n != len(values) { return fmt.Errorf("expected %d values, got %d", len(values), n) } return nil } func main() { var id int var name string var score float64 input := "101 Alice 95.5" err := scanValues(input, &id, &name, &score) if err != nil { fmt.Println("Error:", err) return } fmt.Printf("ID: %d, Name: %s, Score: %.1f\n", id, name, score) }
scanValues
函数接受任意数量的指针进行扫描。它提供了对扫描项目计数的额外验证。
使用自定义分隔符扫描
虽然 fmt.Sscan
默认使用空格,但我们可以预处理字符串以处理其他分隔符。此示例显示了逗号分隔的解析。
package main import ( "fmt" "strings" ) func main() { var item string var quantity int var price float64 input := "apple,5,1.99" // Replace commas with spaces normalized := strings.ReplaceAll(input, ",", " ") n, err := fmt.Sscan(normalized, &item, &quantity, &price) if err != nil { fmt.Println("Error scanning:", err) return } fmt.Printf("Scanned %d items: %d %s at $%.2f each\n", n, quantity, item, price) }
代码在扫描前将逗号转换为空格。此技术适用于简单情况,但对于复杂解析,请考虑使用 strings.Split
。
使用 Sscanf 进行高级扫描
为了更精确地控制解析,fmt.Sscanf
提供了格式化扫描。此示例比较了 Sscan 和 Sscanf。
package main import ( "fmt" ) func main() { var a, b, c int input := "10-20-30" // Using Sscan (requires space separation) n1, err1 := fmt.Sscan(strings.ReplaceAll(input, "-", " "), &a, &b, &c) fmt.Printf("Sscan: %d,&v → %d %d %d\n", n1, err1, a, b, c) // Using Sscanf with format string n2, err2 := fmt.Sscanf(input, "%d-%d-%d", &a, &b, &c) fmt.Printf("Sscanf: %d,&v → %d %d %d\n", n2, err2, a, b, c) }
fmt.Sscanf
提供了对格式说明符的更精确控制。根据您的解析需求,在 Sscan 和 Sscanf 之间进行选择。
来源
本教程通过字符串解析和格式化输入处理的实际示例,涵盖了 Go 中的 fmt.Sscan
函数。