ZetCode

Golang fmt.Scanln 函数

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

本教程将介绍如何在 Go 中使用 `fmt.Scanln` 函数。我们将通过实际示例演示读取用户输入的输入基础知识。

`fmt.Scanln` 函数用于在 Go 中读取用户输入。它从标准输入扫描文本,将连续的空格分隔值存储到参数中。它在换行符处停止扫描。

在 Go 中,`fmt.Scanln` 类似于 `fmt.Scan`,但它会在换行符处停止扫描。它通常用于简单的命令行输入场景,当你想读取直到用户按下 Enter 键时。

fmt.Scanln 基本示例

`fmt.Scanln` 最简单的用法是从输入中读取单个值。本示例演示了如何从用户那里读取字符串。
注意: 输入读取直到第一个空格或换行符。

basic_scanln.go
package main

import "fmt"

func main() {
    var name string
    
    fmt.Print("Enter your name: ")
    fmt.Scanln(&name)
    
    fmt.Printf("Hello, %s!\n", name)
}

该程序会提示输入姓名,使用 `fmt.Scanln` 读取姓名,然后向用户打招呼。`&` 运算符获取变量的内存地址。

读取多个值

`fmt.Scanln` 可以在一次调用中读取多个值。本示例展示了如何读取用空格分隔的多个值。

multiple_values.go
package main

import "fmt"

func main() {
    var firstName, lastName string
    var age int
    
    fmt.Print("Enter first name, last name and age: ")
    fmt.Scanln(&firstName, &lastName, &age)
    
    fmt.Printf("%s %s is %d years old\n", firstName, lastName, age)
}

该函数将空格分隔的值读取到提供的变量中。当所有变量都已填充或遇到换行符时,输入停止。

处理输入错误

我们可以检查 `fmt.Scanln` 的返回值来检测输入错误。本示例展示了基本的错误处理。

error_handling.go
package main

import "fmt"

func main() {
    var number int
    
    fmt.Print("Enter a number: ")
    if _, err := fmt.Scanln(&number); err != nil {
        fmt.Println("Invalid input:", err)
        return
    }
    
    fmt.Printf("You entered: %d\n", number)
}

第二个返回值是一个错误,指示扫描是否失败。当期望特定类型的输入(如数字)时,这很有用。

读取直到换行符

与 `fmt.Scan` 不同,`fmt.Scanln` 在换行符处停止。本示例演示了行为上的差异。

newline_behavior.go
package main

import "fmt"

func main() {
    var a, b string
    
    fmt.Println("Using Scanln (enter two words):")
    fmt.Scanln(&a, &b)
    fmt.Printf("Scanln got: %q and %q\n", a, b)
    
    fmt.Println("Using Scan (enter two words):")
    fmt.Scan(&a, &b)
    fmt.Printf("Scan got: %q and %q\n", a, b)
}

`fmt.Scanln` 只会读取直到第一个换行符的输入。`fmt.Scan` 如果需要,将继续从后续行读取。

读取混合数据类型

`fmt.Scanln` 可以在一次调用中处理不同的变量类型。本示例展示了如何同时读取字符串和数字。

mixed_types.go
package main

import "fmt"

func main() {
    var product string
    var price float64
    
    fmt.Print("Enter product name and price: ")
    if _, err := fmt.Scanln(&product, &price); err != nil {
        fmt.Println("Error:", err)
        return
    }
    
    fmt.Printf("%s costs $%.2f\n", product, price)
}

该函数根据目标变量自动将输入转换为正确的类型。无效的转换会返回错误。

读取到切片中

我们可以通过读取到单个元素来使用 `fmt.Scanln` 和切片。本示例演示了如何将多个值读取到切片中。

slice_input.go
package main

import "fmt"

func main() {
    var numbers = make([]int, 3)
    
    fmt.Print("Enter three numbers: ")
    fmt.Scanln(&numbers[0], &numbers[1], &numbers[2])
    
    sum := numbers[0] + numbers[1] + numbers[2]
    fmt.Printf("Sum: %d\n", sum)
}

每个切片元素都必须单独寻址。该函数将值直接读取到切片的元素中。

高级错误处理

为了进行健壮的输入处理,我们可以将 `fmt.Scanln` 与其他技术结合使用。本示例展示了一个更完整的解决方案。

advanced_error.go
package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
    "strings"
)

func main() {
    reader := bufio.NewReader(os.Stdin)
    
    fmt.Print("Enter two numbers: ")
    input, _ := reader.ReadString('\n')
    input = strings.TrimSpace(input)
    parts := strings.Split(input, " ")
    
    if len(parts) != 2 {
        fmt.Println("Please enter exactly two numbers")
        return
    }
    
    num1, err1 := strconv.Atoi(parts[0])
    num2, err2 := strconv.Atoi(parts[1])
    
    if err1 != nil || err2 != nil {
        fmt.Println("Please enter valid numbers")
        return
    }
    
    fmt.Printf("Sum: %d\n", num1+num2)
}

这种方法提供了对输入解析和错误处理的更多控制。当 `fmt.Scanln` 的行为过于严格时,它很有用。

来源

Go 包文档

本教程通过读取和处理用户输入的实际示例,涵盖了 Go 中的 `fmt.Scanln` 函数。

作者

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

列出所有 Golang 教程