ZetCode

Golang fmt.Scanf 函数

最后修改时间 2025 年 5 月 8 日

本教程解释了如何在 Go 中使用 fmt.Scanf 函数。我们将通过格式化输入的实际示例来介绍输入解析基础知识。

fmt.Scanf 函数从标准输入读取文本,根据格式字符串将连续的空格分隔的值存储到参数中。它返回成功扫描的项目数。

在 Go 中,fmt.Scanf 类似于 C 的 scanf,但具有类型安全。它对于解析具有已知格式的结构化输入数据非常有用。除非格式中另有规定,否则该函数会在换行符处停止扫描。

基本 fmt.Scanf 示例

fmt.Scanf 最简单的用法是从输入读取单个值。此示例演示了基本的整数输入解析。
注意: 务必检查返回值以确保扫描成功。

basic_scanf.go
package main

import "fmt"

func main() {
    var age int
    
    fmt.Print("Enter your age: ")
    n, err := fmt.Scanf("%d", &age)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d value(s): Age = %d\n", n, age)
}

该程序从标准输入读取一个整数。%d 动词匹配十进制整数。我们将结果存储在 age 变量中。

读取多个值

fmt.Scanf 可以在一次调用中解析多个值。此示例展示了如何同时读取不同的数据类型。

multiple_values.go
package main

import "fmt"

func main() {
    var name string
    var age int
    var height float64
    
    fmt.Print("Enter name, age, and height: ")
    n, err := fmt.Scanf("%s %d %f", &name, &age, &height)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d values:\n", n)
    fmt.Printf("Name: %s\nAge: %d\nHeight: %.2f\n", 
        name, age, height)
}

格式字符串 "%s %d %f" 匹配一个字符串、一个整数和一个浮点数。输入中的值必须用空格分隔。顺序必须与变量匹配。

处理带空格的字符串输入

默认情况下,%s 在遇到空格时停止。此示例演示了如何读取包含空格的整个行或字符串。

string_with_spaces.go
package main

import "fmt"

func main() {
    var firstName, lastName string
    
    fmt.Print("Enter your full name: ")
    n, err := fmt.Scanf("%s %s", &firstName, &lastName)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d names:\n", n)
    fmt.Printf("First: %s\nLast: %s\n", firstName, lastName)
}

这会将两个单独的单词读入不同的变量。对于带有中间名的全名,请考虑改用 bufio.Scanner

使用 fmt.Scanf 自定义分隔符

fmt.Scanf 可以使用格式字符串解析带有自定义分隔符的输入。此示例演示了逗号分隔值解析。

custom_delimiters.go
package main

import "fmt"

func main() {
    var x, y int
    
    fmt.Print("Enter coordinates (x,y): ")
    n, err := fmt.Scanf("%d,%d", &x, &y)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d values: (%d, %d)\n", n, x, y)
}

格式字符串 "%d,%d" 期望用逗号分隔的两个整数。为了成功解析,输入必须精确匹配此格式。

读取直到换行符

要一直读取到换行符,请在格式字符串中包含 \n。此示例演示了如何消耗整个输入行。

read_until_newline.go
package main

import "fmt"

func main() {
    var message string
    
    fmt.Print("Enter a message: ")
    n, err := fmt.Scanf("%[^\n]\n", &message)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d values:\nMessage: %q\n", 
        n, message)
}

格式 %[^\n]\n 读取所有字符直到换行符,然后消耗该换行符。这允许读取带空格的字符串。

使用 fmt.Scanf 验证输入

fmt.Scanf 可以在扫描过程中验证输入格式。此示例演示了日期格式验证。

input_validation.go
package main

import "fmt"

func main() {
    var day, month, year int
    
    fmt.Print("Enter date (dd-mm-yyyy): ")
    n, err := fmt.Scanf("%d-%d-%d", &day, &month, &year)
    
    if err != nil || n != 3 {
        fmt.Println("Invalid date format")
        return
    }
    
    fmt.Printf("Date: %02d/%02d/%04d\n", day, month, year)
}

格式 "%d-%d-%d" 确保输入匹配 dd-mm-yyyy 模式。返回值检查是否成功解析了所有三个值。

高级格式动词

fmt.Scanf 支持各种数据类型的格式动词。此示例显示了十六进制和布尔输入解析。

format_verbs.go
package main

import "fmt"

func main() {
    var hexValue int
    var flag bool
    var str string
    
    fmt.Print("Enter hex, bool, string (ex: 0x1A true text): ")
    n, err := fmt.Scanf("%x %t %s", &hexValue, &flag, &str)
    
    if err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("Scanned %d values:\n", n)
    fmt.Printf("Hex: %#x\nBool: %t\nString: %q\n", 
        hexValue, flag, str)
}

%x 动词解析十六进制数,%t 解析布尔值,%s 解析字符串。每个动词都匹配输入中其特定类型。

来源

Go fmt 包文档

本教程通过格式化输入解析和验证的实际示例,介绍了 Go 中的 fmt.Scanf 函数。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。到目前为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Golang 教程