【Go语言基础【9】】字符串格式化与输入处理

文章目录

Go语言通过fmt包提供强大的字符串格式化功能,支持输出格式化、输入解析及字符串操作。

场景 推荐函数 格式字符串示例 说明
简单空格分隔输入 Scan/Scanln - 适用于姓名、年龄等简单数据
自定义格式输入 Scanf %s:%d 解析带分隔符的数据(如KV对)
从字符串解析数据 SScanf %d-%s 处理日志、配置等字符串数据
读取整行(含空格) bufio.Reader + SScan - 先读取整行,再按需解析

一、 格式化输出(Print家族)

1. 核心函数

函数名 说明
Print 按原样输出值,用空格分隔,不换行
Println 输出值并换行,自动添加换行符
Printf 按指定格式输出(核心格式化函数)
Sprintf 格式化并返回字符串(不输出到控制台)
Fprintf 格式化并输出到io.Writer(如文件、网络连接)

2、 格式化占位符(常用)

占位符 类型 说明
%d 整数 十进制表示(如 %03d 补零至3位)
%s 字符串 输出字符串(如 %-10s 左对齐,宽度10)
%f 浮点数 固定小数位(如 %.2f 保留2位小数)
%t 布尔值 true/false
%v 通用 值的默认格式(结构体输出字段值,切片输出元素)
%+v 通用 结构体输出带字段名(如 {Name:Alice Age:25}
%#v 通用 Go语法表示(如 "string"[]int{1,2,3}
%T 类型 输出类型(如 int[]string
%% 字面量 输出 % 符号

示例:格式化输出

go 复制代码
package main

import "fmt"

func main() {
    name := "Alice"
    age := 25
    score := 95.5

    // 基础格式化
    fmt.Printf("姓名:%s,年龄:%d,分数:%.1f\n", name, age, score)
    // 输出:姓名:Alice,年龄:25,分数:95.5

    // 宽度与对齐
    fmt.Printf("|%10s|", name)   // 右对齐,宽度10 → "|     Alice|"
    fmt.Printf("|%-10s|\n", name) // 左对齐,宽度10 → "|Alice     |"

    // 结构体格式化
    type User struct { Name string; Age int }
    user := User{"Bob", 30}
    fmt.Printf("%+v\n", user) // 带字段名 → {Name:Bob Age:30}
    fmt.Printf("%#v\n", user) // Go语法 → main.User{Name:"Bob", Age:30}
}

二、 格式化输入

fmt包提供3组输入函数,用于从不同数据源读取数据:

  • Scan家族 :从标准输入(os.Stdin)读取
  • SScan家族:从字符串中读取
  • Fscan家族 :从io.Reader(如文件、网络流)读取

1、Scan家族:标准输入

函数名 说明
Scan 按空格/换行符分割输入,换行符视为空格,读取到足够参数后停止
Scanln 遇到换行符或EOF时停止,换行符作为终止符(非分隔符)
Scanf 按指定格式解析输入(支持自定义分隔符和格式)

示例1:Scan(空格/换行分隔)

go 复制代码
package main
import "fmt"

func main() {
	scanExample()
}

func scanExample() {
	var name string
	var age int
	fmt.Print("请输入姓名和年龄(空格或换行分隔):")
	// 输入示例:"Tom\n20" 或 "Tom 20"
	fmt.Scan(&name, &age) // 换行符视为空格,读取两个参数
	fmt.Printf("姓名:%s,年龄:%d\n", name, age)
}

示例2:Scanln(换行终止)

go 复制代码
func scanlnExample() {
    var name string
    var age int
    fmt.Print("请输入姓名和年龄(换行分隔):")
    // 输入示例:"Tom\n20"(换行分隔)
    fmt.Scanln(&name, &age) // 遇到换行符停止,读取两个参数
    fmt.Printf("姓名:%s,年龄:%d\n", name, age)
}

示例3:Scanf(自定义格式)

go 复制代码
func scanfExample() {
    var name string
    var age int
    fmt.Print("请输入姓名:年龄(如 Alice:25):")
    // 格式字符串 "%s:%d" 匹配 "姓名:年龄" 格式
    fmt.Scanf("%s:%d", &name, &age) // 分隔符为 ":"
    fmt.Printf("姓名:%s,年龄:%d\n", name, age)
}

2、SScan家族:字符串输入

从字符串中解析数据,用法与Scan家族一致,仅数据源为字符串。

示例:SScanf(从字符串解析)

go 复制代码
func sscanfExample() {
	input := "Bob 30 male"
	var name string
	var age int
	var gender string
	// 格式字符串 "%s %d %s" 匹配 "姓名 年龄 性别"
	fmt.Sscanf(input, "%s %d %s", &name, &age, &gender)
	fmt.Printf("解析结果:姓名=%s,年龄=%d,性别=%s\n", name, age, gender)
	// 输出:解析结果:姓名=Bob,年龄=30,性别=male
}

3、返回值处理

所有Scan函数返回两个值:

  • n int:成功读取的参数数量
  • err error:错误信息(如类型不匹配、参数不足)

示例:错误处理

go 复制代码
func scanErrorHandling() {
    var age int
    n, err := fmt.Scan(&age) // 输入非整数(如 "abc")
    if err != nil {
        fmt.Printf("读取失败:%v\n", err) // 输出:invalid syntax
    } else if n < 1 {
        fmt.Println("未读取到有效数据")
    } else {
        fmt.Printf("成功读取年龄:%d\n", age)
    }
}

三、基于bufio读取数据

我们可以从IO流中读取数据再配合Sscan 就完成了基于网络的Scan

这里采用bufio从标准输入读取数据, 真实案例你可以从Socket读取数据 发送过来

go 复制代码
func readFullName() {
	var (
		name string
		age  uint
	)
	fmt.Print("请输入你的姓名和年龄, 以空格分隔: ")
	stdin := bufio.NewReader(os.Stdin)
	line, _, err := stdin.ReadLine()
	if err != nil {
		panic(err)
	}
	n, err := fmt.Sscanln(string(line), &name, &age)
	if err != nil {
		panic(err)
	}
	fmt.Printf("read number of items: %d", n)
	fmt.Println()
	fmt.Printf("姓名: %s 年龄: %d", name, age)
	fmt.Println()
	
	/**
	请输入你的姓名和年龄, 以空格分隔: gaoliang 222
	read number of items: 2
	姓名: gaoliang 年龄: 222
	 */
}
相关推荐
比特森林探险记13 小时前
Go 中的 Map 与字符处理指南
c++·算法·golang
比特森林探险记13 小时前
Go 中 map 的双值检测写法详解
java·前端·golang
哆啦A梦158813 小时前
在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/[email protected] 更换为 go-ansible/@v1.1.7
开发语言·golang·ansible
LanLance14 小时前
ES101系列09 | 运维、监控与性能优化
java·运维·后端·elasticsearch·云原生·性能优化·golang
Toby_00915 小时前
tpc udp http
其他·golang
弱冠少年15 小时前
golang入门
开发语言·后端·golang
roman_日积跬步-终至千里1 天前
【Go语言基础【3】】变量、常量、值类型与引用类型
开发语言·算法·golang
roman_日积跬步-终至千里1 天前
【Go语言基础】基本语法
开发语言·golang·xcode
月忆3642 天前
go语言的锁
golang