Skip to content

输入与格式化

Updated View as Markdown

fmt 模块类似 C++ 中的 iostream,C 中的 stdio.h

接下来开始讲述。

处理输入

使用 fmt 包提供的 Scan 和 Sscan 开头的函数

// 从控制台读取输入:
package main
import "fmt"

var (
   firstName, lastName, s string
   i int
   f float32
   input = "56.12 / 5212 / Go"
   format = "%f / %d / %s"
)

func main() {
   fmt.Println("Please enter your full name: ")
   fmt.Scanln(&firstName, &lastName)
   // fmt.Scanf("%s %s", &firstName, &lastName)
   fmt.Printf("Hi %s %s!\n", firstName, lastName) // Hi Chris Naegels
   fmt.Sscanf(input, format, &f, &i, &s)
   fmt.Println("From the string we read: ", f, i, s)
    // 输出结果: From the string we read: 56.12 5212 Go
}

运行

go mod tidy;go run .

输出

C:\Users\Administrator\Desktop\git\0>go run .
Please enter your full name:
Chris Naegels
Hi Chris Naegels !
From the string we read:  56.12 5212 Go

解析

我们分三部分讲这里的过程。

引入 fmt,声明变量

在这里开头,先使用 var() 声明了一堆变量

让我们首先关注 firstName 和 lastName。

和这两个函数相关的代码我们单独抽出来:


package main

import "fmt"

var (

	firstName, lastName string

)

func main() {

	fmt.Println("Please enter your full name: ")

	fmt.Scanln(&firstName, &lastName)

	// fmt.Scanf("%s %s", &firstName, &lastName)

	fmt.Printf("Hi %s %s!\\n", firstName, lastName) // Hi Chris Naegels

}

声明这两个函数为 string 类型,随即打印 Please enter your full name:

在此之fmt.Scanln(&firstName, &lastName) 让用户输入,以空格分割两个变量(从注释中 fmt.Scanf("%s %s", &firstName, &lastName) 不难看出)

然后再将两个变量打印。

input,f,i,s,format 四个变量

在这四个变量中 format 变量是把 input变量转换为 f,i,s 的格式化的规范。

在开头定义了 input 的值为

56.12 / 5212 / Go

在这之中,56.12 为小数 float5212 为整数 intGo 为字符串 string

最终通过 fmt.Sscanf(input, format, &f, &i, &s) 进行格式化。\

fmt.Sscanf() 中发生了什么?

不难看出fmt.Sscanf() 中,输入的一方为 &[变量名]

那么 inputformat 作为输入值,经过 format 格式化后,赋值进入 f,i,s 中。

因此,经过复制后,是这样的过程(mermaid 流程由 AI 生成)。

graph LR
A["input: 56.12 / 5212 / Go"] --> B[fmt.Sscanf]
C["format: %f / %d / %s"] --> B
B --> D[f = 56.12]
B --> E[i = 5212]
B --> F[s = Go]

从此之后,关于 Go 的输入输出基本够用了。

格式化输出(fmt 的格式化能力)

在 Go 语言中,fmt 不仅可以处理输入,还提供了非常强大的“格式化输出能力”,类似 C 语言中的 printf 系列函数。


格式化输出到控制台

fmt.Printf 用于按照指定格式输出内容。

package main

import "fmt"

func main() {
	name := "Go"
	age := 15
	score := 98.5

	fmt.Printf("name=%s, age=%d, score=%.1f\n", name, age, score)
}

输出结果:

> name=Go, age=15, score=98.5

常用格式化占位符(verbs)

Go 的格式化符号非常重要,几乎所有 fmt 输出都会用到:

占位符 说明 示例
%s 字符串 "Go"
%d 十进制整数 123
%f 浮点数 3.14
%.2f 保留 2 位小数的浮点数 3.14
%t 布尔值 true
%v 默认格式 任意类型
%T 类型 int / string
%+v 显示字段名(结构体) {Field:Value}

生成格式化字符串

Sprintf 不输出而返回一个字符串。

package main

import "fmt"

func main() {
	name := "Gopher"
	age := 20

	result := fmt.Sprintf("name=%s, age=%d", name, age)
	fmt.Println(result)
}

输出:

name=Gopher, age=20

多用于拼接字符串

写入到指定输出流

可以把格式化内容写入文件或其他输出目标。

package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Fprintf(os.Stdout, "Hello %s!\n", "World")
}

输出:

Hello World!

os.Stdout 表示标准输出,也可以替换为文件句柄。

Sscanf 的本质

我们之前用过:

fmt.Sscanf(input, format, &f, &i, &s)

按照 format 规则,从字符串中解析数据。

示例:

package main

import "fmt"

func main() {
	input := "56.12 / 5212 / Go"

	var f float64
	var i int
	var s string

	fmt.Sscanf(input, "%f / %d / %s", &f, &i, &s)

	fmt.Println(f, i, s)
}

输出:

56.12 5212 Go

总结

输出:Printf / Sprintf / Fprintf

输入解析:Scan / Scanf / Sscanf

参考:

Navigation

Type to search…

↑↓ navigate↵ selectEsc close