【go】fmt包讲解与案例
Go 中的 fmt 包
fmt 包是 Go 语言标准库中用于格式化和输入输出的核心工具。
提供多种函数实现字符串输出、格式化输入输出、用户交互等功能。
fmt 包的常用输出函数
- Print:直接输出内容,不带换行符。
- Println:输出内容,并在末尾添加换行符。
- Printf:按指定格式输出内容(支持占位符,如
%d
、%s
等)。 - Sprint:格式化内容为字符串,返回结果而非直接输出。
- Fprint:将格式化内容输出到指定的 io.Writer(如文件)。
示例:
package main
import "fmt"
func main() {
// 普通输出
fmt.Print("普通输出:")
fmt.Println("Hello, World!")
// 格式化输出
name := "Alice"
age := 25
fmt.Printf("名字:%s,年龄:%d\n", name, age)
// 返回格式化字符串
message := fmt.Sprintf("欢迎 %s,您今年 %d 岁!", name, age)
fmt.Println(message)
}
输出结果:
普通输出:Hello, World!
名字:Alice,年龄:25
欢迎 Alice,您今年 25 岁!
fmt 包的格式化占位符
- 通用占位符
%v
:按变量原始值输出。%+v
:显示结构体字段名和值。%#v
:按 Go 语法格式输出值。%T
:输出变量类型。%%
:输出百分号%
。
- 数据类型相关占位符
- 布尔值:
%t
- 整型:
%d
(十进制)、%b
(二进制)、%x
(十六进制) - 浮点型:
%f
、%e
(科学计数法)、%g
- 字符串:
%s
- 指针:
%p
- 布尔值:
示例:
package main
import "fmt"
func main() {
num := 42
str := "Go语言"
boolean := true
fmt.Printf("整数:%d,二进制:%b,十六进制:%x\n", num, num, num)
fmt.Printf("字符串:%s,布尔值:%t\n", str, boolean)
fmt.Printf("变量类型:%T\n", str)
}
输出结果:
整数:42,二进制:101010,十六进制:2a
字符串:Go语言,布尔值:true
变量类型:string
fmt 包的输入函数
- Scan:从标准输入读取值,按空格分隔多个变量。
- Scanln:读取值并在换行处停止。
- Scanf:按格式读取输入值(如 “请输入%d”)。
示例:
package main
import "fmt"
func main() {
var name string
var age int
fmt.Print("请输入您的名字:")
fmt.Scanln(&name)
fmt.Print("请输入您的年龄:")
fmt.Scanln(&age)
fmt.Printf("你好,%s!您今年 %d 岁。\n", name, age)
}
输入示例:
请输入您的名字:Alice
请输入您的年龄:30
输出结果:
你好,Alice!您今年 30 岁。
总结
- fmt 包是 Go 中处理输入输出的核心库,支持格式化操作和用户交互。
- 常用函数包括 Print、Printf、Scan、Scanf 等,功能覆盖广泛。
- 提供灵活的占位符,支持多种数据类型的格式化操作。
代码案例
package _case
import (
"bufio"
"fmt"
"os"
"strings"
)
func FmtCase() {
// fmt包主要分为
// 向外输出内容和
// 获取输入内容两大部分。
// 1.x 向外输出
// 1.1 Print系列 会将内容输出到系统的标准输出
// 1.1.1 Print
fmt.Print("在终端打印信息")
// 1.1.2 Printf
name := "kk"
fmt.Printf("我是:%s\n", name)
// 1.1.3 Println
fmt.Println("自动换行")
// 1.2 Fprintf系列 会将内容输出到一个io.Writer接口类型的变量w中(os包三个可用变量,Stdout标准输出, Stdin标准输入, Stderr标准错误),我们通常用这个函数往文件中写入内容。
// 1.2.1 Fprint
n, err := fmt.Fprint(os.Stdout, "输出到标准输出Stdout\n")
// 1.2.1 Fprintf
n, err = fmt.Fprintf(os.Stdout, "输出到标准输入%s\n, num: %d, err: %v\n", "stdin", n, err)
// 1.2.1 Fprintln
n, err = fmt.Fprintln(os.Stdout, "输出到错误输出Stderr")
// 1.3 Sprint系列函数会把传入的数据生成并返回一个字符串。
// 1.3.1 Sprint
s1 := fmt.Sprint("kk")
// 1.3.1 Sprintf
name, age := "ku", 18
s2 := fmt.Sprintf("name:%s, age: %d", name, age)
// 1.3.1 Sprintln
s3 := fmt.Sprintln("ku")
fmt.Println(s1, s2, s3)
// 1.4 Errorf函数根据format参数生成格式化字符串%w包裹错误并返回一个包含该字符串的错误。
// 1.4.1 Errorf
err = fmt.Errorf("a error%w\n", err)
// 通用占位符
type simple struct {
value int
}
a := simple{
value: 10,
}
fmt.Printf("默认格式的值:%v \n", a)
fmt.Printf("包含字段名的值:%+v \n", a)
fmt.Printf("go语法表示的值:%#v \n", a)
fmt.Printf("go语法表示的类型:%T \n", a)
fmt.Printf("双%%:100%% \n")
// bool型占位符
fmt.Printf("bool: %t\n", true)
// 整数占位符
v1 := 10 // 对应码点转字符为\n
fmt.Printf("二进制:%b \n", v1)
fmt.Printf("Unicode码点转字符:%c \n", v1)
fmt.Printf("十进制: %d \n", v1)
fmt.Printf("八进制: %o \n", v1)
fmt.Printf("以0o为前缀的八进制: %O \n", v1)
fmt.Printf("16进制: %x \n", v1)
fmt.Printf("16进制大写字母表示: %X \n", v1)
fmt.Printf("用单引号将字符值包裹: %q \n", v1)
fmt.Printf("Unicode格式: %U \n", v1)
//浮点数与复数占位符
f := 12.34
f2 := 12.3231313131313000
fmt.Printf("二进制科学计数法:%b\n", f)
fmt.Printf("科学计数法:%e\n", f)
fmt.Printf("科学计数法E:%E\n", f)
fmt.Printf("小数:%f\n", f)
fmt.Printf("小数:%F\n", f)
fmt.Printf("自适应%%e或者%%f(更简洁):%g\n", f)
fmt.Printf("自适应%%e或者%%f(更简洁):%g\n", f2)
fmt.Printf("自适应%%E或者%%F(更简洁):%G\n", f)
// 宽度标识符
n1 := 88.88
fmt.Printf("%f\n", n1)
fmt.Printf("%9.f\n", n1)
fmt.Printf("%.2f\n", n1)
fmt.Printf("%9.2f\n", n1)
fmt.Printf("%9f\n", n1)
// 字符串和[]byte
s := "枯藤"
s11 := []byte{'a', 'b', 'c'}
s12 := []byte{65, 66, 67}
fmt.Printf("直接输出字符串或者[]byte:%s\n", s)
fmt.Printf("直接输出字符串或者[]byte:%s\n", s11)
fmt.Printf("直接输出字符串或者[]byte:%s\n", s12)
fmt.Printf("该值对应的双引号括起来的go语法字面量:%q\n", s11)
fmt.Printf("每个字节用两字符16进制表示:%x\n", s)
fmt.Printf("每个字节用两字符16进制表示:%X\n", s)
// 指针
a1 := 18
fmt.Printf("加上0x的16进制地址值:%p\n", &a1)
fmt.Printf("不加上0x的16进制地址值:%#p\n", &a1)
// 2.x 获取输入
// 2.1 Scan系列
// 2.1.1 Scan 从标准输入中扫描用户输入的数据,将以空白符分隔的数据分别存入指定的参数。
var (
Name string
Age int
Married bool
)
_, err = fmt.Scan(&Name, &Age, &Married)
if err != nil {
return
}
fmt.Printf("扫描结果 name: %s, age: %d, married:%t\n", Name, Age, Married)
// 2.1.1 Scanf 为输入数据指定了具体的输入内容格式,只有按照格式输入数据才会被扫描并存入对应变量。
fmt.Println("请按照格式输入:(1: %s 2: %d 3:%t):")
_, err = fmt.Scanf("1: %s 2: %d 3: %t", &Name, &Age, &Married)
fmt.Printf("扫描结果 name: %s, age: %d, married: %t\n", Name, Age, Married)
// 2.1.1 Scanln Scanln类似Scan,它在遇到换行时才停止扫描。最后一个数据后面必须有换行或者到达结束位置。
_, _ = fmt.Scanln(&Name, &Age, &Married)
fmt.Printf("扫描结果 name: %s, age: %d, married: %t\n", Name, Age, Married)
// 2.2 Fscan系列 类似于fmt.Scan、fmt.Scanf、fmt.Scanln三个函数,只不过它们不是从标准输入中读取数据而是从io.Reader中读取数据。
// 2.2.1 Fscan
// 2.2.1 Fscanf
// 2.2.1 Fscanln
// 2.3 Sscan系列 类似于fmt.Scan、fmt.Scanf、fmt.Scanln三个函数,只不过它们不是从标准输入中读取数据而是从指定字符串中读取数据。
// 2.3.1 Sscan
// 2.3.1 Sscanf
// 2.3.1 Sscanln
// 2.3 bufio.NewReader 有时候我们想完整获取输入的内容,而输入的内容可能包含空格,这种情况下可以使用bufio包来实现。
reader := bufio.NewReader(os.Stdin) // 从标准输入生成读对象
fmt.Print("请输入:")
text, _ := reader.ReadString('\n') // 读到换行结束
text = strings.TrimSpace(text) // 删除所有前导和尾部空格
fmt.Printf("%#v\n", text)
}