📅 2024年4月28日
📦 使用版本为 1.21.5
输入输出
标准输出输入重定向
⭐️ 输入重定向是指把文件导入到命令中,输出重定向是指把原本要输出到屏幕的数据写入到指定文件中(这句话是我从我的linux笔记复制过来的)
- 标准输入重定向(STDNI,文件描述符为0):默认从键盘输入,也可以从其他文件或命令中输入。
- 标准输出重定向(STDOUT,文件描述符为1):默认输出到屏幕。
- 错误输出重定向(STDERR,文件描述符为2);默认输出到屏幕。
⭐️ 源代码
在 os
包下的 file
中
1️⃣ 它们类型都是 *File
(这个是一个结构体指针,它指向一个打开的文件,并提供了一些方法来操作这个文件,到文件应该会详细学)
// Stdin、Stdout和Stderr是指向标准输入的打开文件,
//标准输出和标准错误文件描述符。
//
//注意,Go运行时在发生严重错误和崩溃时将写入标准错误;
//关闭Stderr可能会导致这些消息转移到其他地方
//保存到稍后打开的文件。
var (
Stdin = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)
输出
⭐️ 输出的方法在 Go
中有三种
1️⃣ 推荐是使用 fmt
,因为它会使用到反射,因此输出的内容通常更容易使人阅读,不过性能很差强人意
func main() {
var name = "Sam"
os.Stdout.WriteString(name + "\n") //调用os.Stdout
fmt.Printf("type %T value %v", name, name) //fmt库的Printf或者Println
println(name) //内置的println
}
格式化输出
⭐️ 需要调用 fmt
包的 Sprintf/Pinrtf
,使用方法和 C
语言的 printf
一样
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 |
输出指针所指向的地址 | 指针类型 |
1️⃣ 演示代码
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
包提供的三个函数
//源代码 scan.go
func Scan(a ...any) (n int, err error) {
return Fscan(os.Stdin, a...)
}
// Scanln is similar to Scan, but stops scanning at a newline and
// after the final item there must be a newline or EOF.
func Scanln(a ...any) (n int, err error) {
return Fscanln(os.Stdin, a...)
}
// Scanf scans text read from standard input, storing successive
// space-separated values into successive arguments as determined by
// the format. It returns the number of items successfully scanned.
// If that is less than the number of arguments, err will report why.
// Newlines in the input must match newlines in the format.
// The one exception: the verb %c always scans the next rune in the
// input, even if it is a space (or tab etc.) or newline.
func Scanf(format string, a ...any) (n int, err error) {
return Fscanf(os.Stdin, format, a...)
}
// 扫描从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)
⭐️ 它们三种使用方法也有不同,但是大致上都类似,它们和C语言很类似,传入一个参数的值需要使用到 &
来传入这个值在内存中的地址,如果单纯不加 &
那么传递的就是一个副本,在方法函数内部无论如何修改都不会影响到本体
1️⃣ Scanf方法,它的使用方法和 C
语言及其相似(因为我不敢说一模一样)
func main() {
var s, s2 string
fmt.Scanf("%s %s", &s, &s2)
fmt.Println(s, s2)
}
2️⃣ Scan和Scanln方法,它们两最大区别就是一个遇到回车停止一个遇到回车也把回车当作空格
func main() {
var s, s2 string
fmt.Scanln(&s, &s2)
fmt.Scan(&s, &s2)
fmt.Println(s, s2)
}
⭐️ go
输入默认的分割符号位空格
func main() {
var s, s2 string
fmt.Scan(&s, &s2)
fmt.Println(s, s2)
}
//输出:
a b //输入
a b //输出
缓冲
🌮 回马枪的时候在学习,找的资料简直就是一笔带过
⭐️ 当对性能有要求时可以使用 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