输入输出
大约 8 分钟
输入输出
package main
import "fmt"
func main() {
fmt.Println("Hello 世界!")
}
第一个入门的案例就是输出这样一个字符串"Hello 世界!"
,这一节就来讲一下在Go中如何进行输入输出。
标准
var (
Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)
在os
包下有三个外暴露的文件描述符,其类型都是*File
,分别是:
Stdin
- 标准输入Stdout
- 标准输出Stderr
- 标准错误
Go中的控制台输入输出都离不开它们。
输出
输出一句Hello 世界!
,比较常用的有三种方法,第一种是调用os.Stdout
os.Stdout.WriteString("Hello 世界!")
第二种是使用内置函数println
println("Hello 世界!")
第三种也是最推荐的一种就是调用fmt
包下的Println
函数
fmt.Println("Hello 世界!")
fmt.Println
会用到反射,因此输出的内容通常更容易使人阅读,不过性能很差强人意。
格式化
0 | 格式化 | 描述 | 接收类型 |
---|---|---|---|
1 | %% | 输出百分号% | 任意类型 |
2 | %s | 输出string /[] byte 值 | string ,[] byte |
3 | %q | 格式化字符串,输出的字符串两端有双引号"" | string ,[] byte |
4 | %d | 输出十进制整型值 | 整型类型 |
5 | %f | 输出浮点数 | 浮点类型 |
6 | %e | 输出科学计数法形式 ,也可以用于复数 | 浮点类型 |
7 | %E | 与**%e **相同 | 浮点类型 |
8 | %g | 根据实际情况判断输出%f 或者%e ,会去掉多余的0 | 浮点类型 |
9 | %b | 输出整型的二进制表现形式 | 数字类型 |
10 | %#b | 输出二进制完整的表现形式 | 数字类型 |
11 | %o | 输出整型的八进制表示 | 整型 |
12 | %#o | 输出整型的完整八进制表示 | 整型 |
13 | %x | 输出整型的小写十六进制表示 | 数字类型 |
14 | %#x | 输出整型的完整小写十六进制表示 | 数字类型 |
15 | %X | 输出整型的大写十六进制表示 | 数字类型 |
16 | %#X | 输出整型的完整大写十六进制表示 | 数字类型 |
17 | %v | 输出值原本的形式,多用于数据结构的输出 | 任意类型 |
18 | %+v | 输出结构体时将加上字段名 | 任意类型 |
19 | %#v | 输出完整Go语法格式的值 | 任意类型 |
20 | %t | 输出布尔值 | 布尔类型 |
21 | %T | 输出值对应的Go语言类型值 | 任意类型 |
22 | %c | 输出Unicode码对应的字符 | int32 |
23 | %U | 输出字符对应的Unicode码 | rune ,byte |
24 | %p | 输出指针所指向的地址 | 指针类型 |
使用fmt.Sprintf
或者fmt.Printf
来格式化字符串或者输出格式化字符串,看几个例子
fmt.Printf("%%%s\n", "hello world")
fmt.Printf("%s\n", "hello world")
fmt.Printf("%q\n", "hello world")
fmt.Printf("%d\n", 2<<7-1)
fmt.Printf("%f\n", 1e2)
fmt.Printf("%e\n", 1e2)
fmt.Printf("%E\n", 1e2)
fmt.Printf("%g\n", 1e2)
fmt.Printf("%b\n", 2<<7-1)
fmt.Printf("%#b\n", 2<<7-1)
fmt.Printf("%o\n", 2<<7-1)
fmt.Printf("%#o\n", 2<<7-1)
fmt.Printf("%x\n", 2<<7-1)
fmt.Printf("%#x\n", 2<<7-1)
fmt.Printf("%X\n", 2<<7-1)
fmt.Printf("%#X\n", 2<<7-1)
type person struct {
name string
age int
address string
}
fmt.Printf("%v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%+v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%#v\n", person{"lihua", 22, "beijing"})
fmt.Printf("%t\n", true)
fmt.Printf("%T\n", person{})
fmt.Printf("%c%c\n", 20050, 20051)
fmt.Printf("%U\n", '码')
fmt.Printf("%p\n", &person{})
错误情况
格式化字符数量 < 参数列表数量
fmt.Printf("", "") //%!(EXTRA string=)
格式化字符数量 > 参数列表数量
fmt.Printf("%s%s", "") //%!s(MISSING)
类型不匹配
fmt.Printf("%s", 1) //%!s(int=1)
缺少格式化动词
fmt.Printf("%", 1) // %!(NOVERB)%!(EXTRA int=1)
输入
输入的话是通常使用fmt
包下提供的三个函数
// 扫描从os.Stdin读入的文本,根据空格分隔,换行也被当作空格
func Scan(a ...any) (n int, err error)
// 与Scan类似,但是遇到换行停止扫描
func Scanln(a ...any) (n int, err error)
// 根据格式化的字符串扫描
func Scanf(format string, a ...any) (n int, err error)
需要注意的是,Go中输入的默认分隔符号是空格,下面看几个例子:
func main() {
var s, s2 string
fmt.Scan(&s, &s2)
fmt.Println(s, s2)
}
a
b
a b
使用fmt.Scanln
func main() {
var s, s2 string
fmt.Scanln(&s, &s2)
fmt.Println(s, s2)
}
a b
a b
使用fmt.Scanf
func main() {
var s, s2, s3 string
scanf, err := fmt.Scanf("%s %s \n %s", &s, &s2, &s3)
if err != nil {
fmt.Println(scanf, err)
}
fmt.Println(s)
fmt.Println(s2)
fmt.Println(s3)
}
aa bb
cc
aa
bb
cc
缓冲
当对性能有要求时可以使用bufio
包进行读取,例如下面这个输入的例子
func main() {
// 读
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
fmt.Println(scanner.Text())
}
abcedfg
abcedfg
输出
func main() {
// 写
writer := bufio.NewWriter(os.Stdout)
writer.WriteString("hello world!\n")
writer.Flush()
fmt.Println(writer.Buffered())
}
hello world!
0