Golang fmt.Fscanln 函数
最后修改时间 2025 年 5 月 8 日
本教程将解释如何在 Go 中使用 fmt.Fscanln
函数。我们将通过实际示例介绍输入扫描基础知识,包括从各种来源读取格式化输入。
fmt.Fscanln
函数从 io.Reader
读取,并将空格分隔的值扫描到连续的参数中。它在换行符处停止扫描,并且在最后一个项目之后,必须有一个换行符或 EOF。
在 Go 中,fmt.Fscanln
类似于 fmt.Scanln
,但它适用于任何 io.Reader
。它对于从文件、网络连接或自定义读取器读取结构化输入非常有用。
Fscanln 的基本用法
fmt.Fscanln
最简单的用法是从字符串读取器读取值。此示例演示了基本的输入扫描。
注意:值必须用空格分隔,并以换行符结尾。
package main import ( "fmt" "strings" ) func main() { input := "John 25 true\n" reader := strings.NewReader(input) var name string var age int var active bool n, err := fmt.Fscanln(reader, &name, &age, &active) if err != nil { fmt.Println("Error:", err) return } fmt.Printf("Read %d values: %s, %d, %t\n", n, name, age, active) }
代码从字符串中读取三种不同的类型。该函数返回成功扫描的项目数以及遇到的任何错误。
从标准输入读取
fmt.Fscanln
可以直接使用 os.Stdin
从标准输入读取。此示例展示了交互式输入扫描。
package main import ( "fmt" "os" ) func main() { fmt.Println("Enter your name and age (separated by space):") var name string var age int n, err := fmt.Fscanln(os.Stdin, &name, &age) if err != nil { fmt.Println("Error:", err) return } fmt.Printf("Hello %s! You are %d years old.\n", name, age) fmt.Printf("Successfully read %d values.\n", n) }
程序等待用户输入并读取两个值。Fscanln
要成功完成,输入后的换行符是必需的。
从文件读取
fmt.Fscanln
通常用于从文件中读取结构化数据。此示例演示了文件输入扫描。
package main import ( "fmt" "os" ) func main() { file, err := os.Open("data.txt") if err != nil { fmt.Println("Error opening file:", err) return } defer file.Close() var product string var price float64 var quantity int _, err = fmt.Fscanln(file, &product, &price, &quantity) if err != nil { fmt.Println("Error reading file:", err) return } fmt.Printf("Product: %s\nPrice: $%.2f\nQuantity: %d\n", product, price, quantity) }
代码从包含产品数据的文件中读取一行。请记住处理文件打开错误并在完成后关闭文件。
处理多行
要读取多行,请在循环中使用 fmt.Fscanln
。此示例展示了如何逐行处理结构化数据。
package main import ( "bufio" "fmt" "strings" ) func main() { data := `Alice 25 Bob 30 Charlie 35` scanner := bufio.NewScanner(strings.NewReader(data)) for scanner.Scan() { line := scanner.Text() reader := strings.NewReader(line) var name string var age int _, err := fmt.Fscanln(reader, &name, &age) if err != nil { fmt.Println("Error:", err) continue } fmt.Printf("%s is %d years old\n", name, age) } }
代码将 bufio.Scanner
与行读取结合使用,并将 Fscanln
与行解析结合使用。这种模式对于结构化文本处理非常高效。
读取不同的数据类型
fmt.Fscanln
可以自动处理各种 Go 类型。此示例演示了从输入中读取混合数据类型。
package main import ( "fmt" "strings" ) func main() { input := "Go 1.21 true 42\n" reader := strings.NewReader(input) var lang string var version float64 var compiled bool var year int n, err := fmt.Fscanln(reader, &lang, &version, &compiled, &year) if err != nil { fmt.Println("Error:", err) return } fmt.Printf("Read %d values:\n", n) fmt.Println("Language:", lang) fmt.Println("Version:", version) fmt.Println("Compiled:", compiled) fmt.Println("Year:", year) }
该函数会自动将输入字符串转换为目标变量类型。如果输入与预期类型不匹配,则会返回转换错误。
错误处理
在使用 fmt.Fscanln
时,正确处理错误至关重要。此示例显示了全面的错误检查。
package main import ( "fmt" "strings" ) func main() { testCases := []string{ "100 200\n", "100\n", "100 abc\n", "100 200 300\n", } for _, input := range testCases { reader := strings.NewReader(input) var a, b int n, err := fmt.Fscanln(reader, &a, &b) fmt.Printf("Input: %q\n", input) if err != nil { fmt.Println(" Error:", err) } else { fmt.Printf(" Read %d values: %d, %d\n", n, a, b) } } }
代码测试了各种输入场景,并展示了 Fscanln
在不同输入下的行为。始终检查返回计数和错误。
读取到切片中
虽然 fmt.Fscanln
需要固定参数,但我们可以通过一些额外的代码读取到切片中。此示例演示了该技术。
package main import ( "fmt" "strings" ) func main() { input := "5 10 15 20 25\n" reader := strings.NewReader(input) var nums []int for { var num int n, err := fmt.Fscanln(reader, &num) if n == 0 || err != nil { break } nums = append(nums, num) } fmt.Println("Read numbers:", nums) fmt.Println("Sum:", sum(nums)) } func sum(nums []int) int { total := 0 for _, n := range nums { total += n } return total }
代码读取数字,直到遇到错误。当您无法预测值的数量时,这种模式对于读取可变长度的输入非常有用。
来源
本教程通过从各种来源读取格式化输入的实际示例,涵盖了 Go 中的 fmt.Fscanln
函数。