Go语言系列之标准库fmt
fmt包实现了类似C语言printf和scanf的格式化I/O。主要分为向外输出内容和获取输入内容两大部分。
向外输出
标准库fmt提供了以下几种输出相关函数。
Print系列函数会将内容输出到系统的标准输出,区别在于Print函数直接输出内容,Printf函数支持格式化输出字符串,Println函数会在输出内容的结尾添加一个换行符。
func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)
举个简单的例子:
func main() {
fmt.Print("在终端打印该信息。")
name := "沙河小王子"
fmt.Printf("我是:%s\n", name)
fmt.Println("在终端打印单独一行显示")
}
执行上面的代码输出:
在终端打印该信息。我是:沙河小王子
在终端打印单独一行显示
Fprint
Fprint系列函数会将内容输出到一个io.Writer接口类型的变量w中,我们通常用这个函数往文件中写入内容。
func Fprint(w io.Writer, a ...interface{}) (n int, err error)
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
举个例子:
// 向标准输出写入内容
fmt.Fprintln(os.Stdout, "向标准输出写入内容")
fileObj, err := os.OpenFile("./xx.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
fmt.Println("打开文件出错,err:", err)
return
}
name := "沙河小王子"
// 向打开的文件句柄中写入内容
fmt.Fprintf(fileObj, "往文件中写如信息:%s", name)
注意,只要满足io.Writer接口的类型都支持写入。
Sprint
Sprint系列函数会把传入的数据生成并返回一个字符串。
func Sprint(a ...interface{}) string
func Sprintf(format string, a ...interface{}) string
func Sprintln(a ...interface{}) string
简单的示例代码如下:
s1 := fmt.Sprint("沙河小王子")
name := "沙河小王子"
age := 18
s2 := fmt.Sprintf("name:%s,age:%d", name, age)
s3 := fmt.Sprintln("沙河小王子")
fmt.Println(s1, s2, s3)
Errorf
Errorf函数根据format参数生成格式化字符串并返回一个包含该字符串的错误。
func Errorf(format string, a ...interface{}) error
通常使用这种方式来自定义错误类型,例如:
err := fmt.Errorf("这是一个错误")
Go1.13版本为fmt.Errorf函数新加了一个%w占位符用来生成一个可以包裹Error的Wrapping Error。
e := errors.New("原始错误e")
w := fmt.Errorf("Wrap了一个错误%w", e)
格式化占位符
*printf系列函数都支持format格式化参数,在这里我们按照占位符将被替换的变量类型划分,方便查询和记忆。
通用占位符
| 占位符 | 说明 |
|---|---|
| %v | 值的默认格式表示 |
| %+v | 类似%v,但输出结构体时会添加字段名 |
| %#v | 值的Go语法表示 |
| %T | 打印值的类型 |
| %% | 百分号 |
示例代码如下:
fmt.Printf("%v\n", 100)
fmt.Printf("%v\n", false)
o := struct{ name string }{"小王子"}
fmt.Printf("%v\n", o)
fmt.Printf("%#v\n", o)
fmt.Printf("%T\n", o)
fmt.Printf("100%%\n")
输出结果如下:
100
false
{小王子}
struct { name string }{name:"小王子"}
struct { name string }
100%
布尔型
| 占位符 | 说明 |
|---|---|
| %t | true或false |
整型
| 占位符 | 说明 |
|---|---|
| %b | 表示为二进制 |
| %c | 该值对应的unicode码值 |
| %d | 表示为十进制 |
| %o | 表示为八进制 |
| %x | 表示为十六进制,使用a-f |
| %X | 表示为十六进制,使用A-F |
| %U | 表示为Unicode格式:U+1234,等价于”U+%04X” |
| %q | 该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示 |
示例代码如下:
n := 65
fmt.Printf("%b\n", n)
fmt.Printf("%c\n", n)
fmt.Printf("%d\n", n)
fmt.Printf("%o\n", n)
fmt.Printf("%x\n", n)
fmt.Printf("%X\n", n)
输出结果如下:
1000001
A
65
101
41
41
浮点数与复数
| 占位符 | 说明 |
|---|---|
| %b | 无小数部分、二进制指数的科学计数法,如-123456p-78 |
| %e | 科学计数法,如-1234.456e+78 |
| %E | 科学计数法,如-1234.456E+78 |
| %f | 有小数部分但无指数部分,如123.456 |
| %F | 等价于%f |
| %g | 根据实际情况采用%e或%f格式(以获得更简洁、准确的输出) |
| %G | 根据实际情况采用%E或%F格式(以获得更简洁、准确的输出) |
示例代码如下:
f := 12.34
fmt.Printf("%b\n", f)
fmt.Printf("%e\n", f)
fmt.Printf("%E\n", f)
fmt.Printf("%f\n", f)
fmt.Printf("%g\n", f)
fmt.Printf("%G\n", f)
输出结果如下:
6946802425218990p-49
1.234000e+01
1.234000E+01
12.340000
12.34
12.34
字符串和[]byte
| 占位符 | 说明 |
|---|---|
| %s | 直接输出字符串或者[]byte |
| %q | 该值对应的双引号括起来的go语法字符串字面值,必要时会采用安全的转义表示 |
| %x | 每个字节用两字符十六进制数表示(使用a-f |
| %X | 每个字节用两字符十六进制数表示(使用A-F) |
示例代码如下:
s := "小王子"
fmt.Printf("%s\n", s)
fmt.Printf("%q\n", s)
fmt.Printf("%x\n", s)
fmt.Printf("%X\n", s)
输出结果如下:
小王子
"小王子"
e5b08fe78e8be5ad90
E5B08FE78E8BE5AD90
指针
| 占位符 | 说明 |
|---|---|
| %p | 表示为十六进制,并加上前导的0x |
示例代码如下:
a := 10
fmt.Printf("%p\n", &a)
fmt.Printf("%#p\n", &a)
输出结果如下:
0xc000094000
c000094000
宽度标识符
宽度通过一个紧跟在百分号后面的十进制数指定,如果未指定宽度,则表示值时除必需之外不作填充。精度通过(可选的)宽度后跟点号后跟的十进制数指定。如果未指定精度,会使用默认精度;如果点号后没有跟数字,表示精度为0。举例如下:
| 占位符 | 说明 |
|---|---|
| %f | 默认宽度,默认精度 |
| %9f | 宽度9,默认精度 |
| %.2f | 默认宽度,精度2 |
| %9.2f | 宽度9,精度2 |
| %9.f | 宽度9,精度0 |
示例代码如下:
n := 12.34
fmt.Printf("%f\n", n)
fmt.Printf("%9f\n", n)
fmt.Printf("%.2f\n", n)
fmt.Printf("%9.2f\n", n)
fmt.Printf("%9.f\n", n)
输出结果如下:
12.340000
12.340000
12.34
12.34
12
其他falg
| 占位符 | 说明 |
|---|---|
| ’+’ | 总是输出数值的正负号;对%q(%+q)会生成全部是ASCII字符的输出(通过转义); |
| ’ ‘ | 对数值,正数前加空格而负数前加负号;对字符串采用%x或%X时(% x或% X)会给各打印的字节之间加空格 |
| ’-’ | 在输出右边填充空白而不是默认的左边(即从默认的右对齐切换为左对齐); |
| ’#’ | 八进制数前加0(%#o),十六进制数前加0x(%#x)或0X(%#X),指针去掉前面的0x(%#p)对%q(%#q),对%U(%#U)会输出空格和单引号括起来的go字面值; |
| ‘0’ | 使用0而不是空格填充,对于数值类型会把填充的0放在正负号后面; |
举个例子:
s := "小王子"
fmt.Printf("%s\n", s)
fmt.Printf("%5s\n", s)
fmt.Printf("%-5s\n", s)
fmt.Printf("%5.7s\n", s)
fmt.Printf("%-5.7s\n", s)
fmt.Printf("%5.2s\n", s)
fmt.Printf("%05s\n", s)
输出结果如下:
小王子
小王子
小王子
小王子
小王子
小王
00小王子
获取输入
Go语言fmt包下有fmt.Scan、fmt.Scanf、fmt.Scanln三个函数,可以在程序运行过程中从标准输入获取用户的输入。
fmt.Scan
函数定签名如下:
func Scan(a ...interface{}) (n int, err error)
- Scan从标准输入扫描文本,读取由空白符分隔的值保存到传递给本函数的参数中,换行符视为空白符。
- 本函数返回成功扫描的数据个数和遇到的任何错误。如果读取的数据个数比提供的参数少,会返回一个错误报告原因。
具体代码示例如下:
func main() {
var (
name string
age int
married bool
)
fmt.Scan(&name, &age, &married)
fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
}
将上面的代码编译后在终端执行,在终端依次输入小王子、28和false使用空格分隔。
$ ./scan_demo
小王子 28 false
扫描结果 name:小王子 age:28 married:false
fmt.Scan从标准输入中扫描用户输入的数据,将以空白符分隔的数据分别存入指定的参数。
fmt.Scanf
函数签名如下:
func Scanf(format string, a ...interface{}) (n int, err error)
- Scanf从标准输入扫描文本,根据format参数指定的格式去读取由空白符分隔的值保存到传递给本函数的参数中。
- 本函数返回成功扫描的数据个数和遇到的任何错误。
代码示例如下:
func main() {
var (
name string
age int
married bool
)
fmt.Scanf("1:%s 2:%d 3:%t", &name, &age, &married)
fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
}
将上面的代码编译后在终端执行,在终端按照指定的格式依次输入小王子、28和false。
$ ./scan_demo
1:小王子 2:28 3:false
扫描结果 name:小王子 age:28 married:false
fmt.Scanf不同于fmt.Scan简单的以空格作为输入数据的分隔符,fmt.Scanf为输入数据指定了具体的输入内容格式,只有按照格式输入数据才会被扫描并存入对应变量。
例如,我们还是按照上个示例中以空格分隔的方式输入,fmt.Scanf就不能正确扫描到输入的数据。
$ ./scan_demo
小王子 28 false
扫描结果 name: age:0 married:false
fmt.Scanln
函数签名如下:
func Scanln(a ...interface{}) (n int, err error)
- Scanln类似Scan,它在遇到换行时才停止扫描。最后一个数据后面必须有换行或者到达结束位置。
- 本函数返回成功扫描的数据个数和遇到的任何错误。
具体代码示例如下:
func main() {
var (
name string
age int
married bool
)
fmt.Scanln(&name, &age, &married)
fmt.Printf("扫描结果 name:%s age:%d married:%t \n", name, age, married)
}
将上面的代码编译后在终端执行,在终端依次输入小王子、28和false使用空格分隔。
$ ./scan_demo
小王子 28 false
扫描结果 name:小王子 age:28 married:false
fmt.Scanln遇到回车就结束扫描了,这个比较常用。
bufio.NewReader
有时候我们想完整获取输入的内容,而输入的内容可能包含空格,这种情况下可以使用bufio包来实现。示例代码如下:
func bufioDemo() {
reader := bufio.NewReader(os.Stdin) // 从标准输入生成读对象
fmt.Print("请输入内容:")
text, _ := reader.ReadString('\n') // 读到换行
text = strings.TrimSpace(text)
fmt.Printf("%#v\n", text)
}
Fscan系列
这几个函数功能分别类似于fmt.Scan、fmt.Scanf、fmt.Scanln三个函数,只不过它们不是从标准输入中读取数据而是从io.Reader中读取数据。
func Fscan(r io.Reader, a ...interface{}) (n int, err error)
func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
Sscan系列
这几个函数功能分别类似于fmt.Scan、fmt.Scanf、fmt.Scanln三个函数,只不过它们不是从标准输入中读取数据而是从指定字符串中读取数据。
func Sscan(str string, a ...interface{}) (n int, err error)
func Sscanln(str string, a ...interface{}) (n int, err error)
func Sscanf(str string, format string, a ...interface{}) (n int, err error)
Go语言系列之标准库fmt的更多相关文章
- Go语言系列之标准库log
Go语言内置的log包实现了简单的日志服务.本文介绍了标准库log的基本使用. 使用Logger log包定义了Logger类型,该类型提供了一些格式化输出的方法.本包也提供了一个预定义的" ...
- Go语言系列之标准库ioutil
ioutil标准库中提供了一些常用.方便的IO操作函数 一.相关方法 func ReadAll(r io.Reader) ([]byte, error) func ReadDir(dirname st ...
- Go语言系列之标准库strconv
Go语言中strconv包实现了基本数据类型和其字符串表示的相互转换. strconv包 strconv包实现了基本数据类型与其字符串表示的转换,主要有以下常用函数: Atoi().Itia().pa ...
- Go语言系列之标准库flag
Go语言内置的flag包实现了命令行参数的解析,flag包使得开发命令行工具更为简单. os.Args 如果你只是简单的想要获取命令行参数,可以像下面的代码示例一样使用os.Args来获取命令行参数. ...
- Go语言系列之标准库os
os包提供了操作系统的系列函数,这些接口不依赖平台.设计为Unix风格的,错误处理是go风格的:调用失败会返回错误值而非错误码.通常错误值里包含更多信息. os包的接口在所有操作系统中都是一致的.非公 ...
- Go语言系列之标准库path/filepath
一.Path包 import "path" path实现了对斜杠分隔的路径进行操作的函数. func IsAbs(path string) bool // 判断是否是一个绝对路径 ...
- c++ 11开始语言本身和标准库支持并发编程
c++ 11开始语言本身和标准库支持并发编程,意味着真正要到编译器从语言和标准库层面开始稳定,估计得到17标准出来.14稳定之后的事情了,根据历史经验,新特性的引入到稳定被广泛采用至少要一个大版本的跨 ...
- windows下的c语言和linux 下的c语言以及C标准库和系统API
1.引出我们的问题? 标准c库都是一样的!大家想必都在windows下做过文件编程,在linux下也是一样的函数名,参数都一样.当时就有了疑问,因为我们非常清楚 其本质是不可能一样的,源于这是俩个操作 ...
- C语言日期时间标准库
用思维导图整理: 代码: #include <stdio.h> #include <time.h> #include <string.h> int main() { ...
随机推荐
- mysql联合索引阻碍修改列数据类型:BLOB/TEXT column 'name' used in key specification without a key length
今天在项目中mysql表中有一个字段数据类型为varchar,长度不够需要换为text类型 当时表是已经存在的表, CREATE TABLE `table_aaa` ( `id` int NOT NU ...
- WebRTC音频通话升级为视频通话
我们有时候在音频通话过程中,想要改成视频通话.如果挂断当前通话再重新发起视频通话就会显得比较麻烦. 因此很多app提供了将音频通话升级成视频通话的功能,同时也有将视频通话降为音频通话的功能. 本文演示 ...
- 『学了就忘』Linux系统定时任务 — 88、循环执行定时任务
目录 1.crond服务管理与访问控制 2.crontab命令的访问控制 3.用户级别的crontab命令 4.crontab命令的注意事项 5.系统的crontab设置 (1)/etc/cronta ...
- Could not synchronize database state with session问题,说保存空
Could not synchronize database state with session问题,说保存空 ,可以在post.hbm.xml文件里设置inverse="true&quo ...
- mysql导入文件 日期时间报错:[Err] 1067 - Invalid default value for 'active_time'
报错原因意思是说:mysql5.7版本中有了一个STRICT mode(严格模式),而在此模式下默认是不允许设置日期时间的值为全0值的,所以想要 解决这个问题,就需要修改sql_mode的值. 修改 ...
- SpringBoot单元测试demo
引入maven <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- 【蓝桥杯】非VIP基础题型训练17题 (Python 题解)
NO.I 基础题型 基础练习汇总 时间 题目 解析 21.12.24 早上 1. A+B问题 练习系统的适应 21.12.24 早上 2. 数组排序 输入输出排序 21.12.24 早上 3. 十六进 ...
- 辅助函数和高阶函数 map、filter、reduce
辅助函数和高阶函数 map.filter.reduce: 一.辅助函数:(1-1)响应式函数 (数组更新检测): push() pop() shift() unshift() ...
- 在制造业的工业2.0中应用MOM系统
介绍 什么是制造运营管理 (MOM) 系统和 IT 架构的最佳实践? 行业专家对制造类型和供应网络有何建议? 管理思维和企业文化是否因不断变化的全球市场而过时? MOM 技术是否过于昂贵,IT 架构是 ...
- 【Android开发】问答机器人,聊天类App的开发制作过程记录
缘起 很久没写项目了,所以单纯的想练练手,正好看到有问答机器人的接口,想到之前也做过聊天项目,为什么不实验一下呢.当然也是简单调用接口的项目,并没有真正的完成问答的算法等等.业余项目,功能不齐全,只实 ...