go-IO操做(一)

格式化输入输出

从终端获取用户的输入,go提供了三个函数:git

//格式化输入,空格做为分隔符,占位符和格式化输出一致
fmt.Scanf(format string, a ...interface{})
//从终端获取用户输入,存储在Scan的参数里,空格和换行符做为分隔符
fmt.Scan(a ...interface{}) 
//从终端获取用户输入,存储在Scanln的参数里,空格做为分隔符,遇到换行符结束
fmt.Scanln(a ...interface{})
复制代码

例子:github

package main

import (
	"fmt"
)

func main() {
	scanf()
	//scan()
	//scanln()
}

func scanf() {
	var a string
	fmt.Scanf("%s", &a)
	fmt.Println("this is input:", a)
}

// go run main.go
// 123
// this is input: 123

func scan() {
	var b int
	var c int
	fmt.Scan(&b, &c)
	fmt.Println("this is input:", b, c)
}

// go run main.go
// 1
// 2
// this is input: 1 2

func scanln() {
	var d int
	var e int
	fmt.Scanln(&d, &e)
	fmt.Println("this is input:", d, e)
}

// go run main.go
// 12 23
// this is input: 12 23

复制代码

同时还能够从字符串中获取输入,跟上面的差很少:golang

fmt.Sscanf(str string, format string, a ...interface{})
fmt.Sscan(str string, a ...interface{})
fmt.Sscanln(str string, a ...interface{})
复制代码

例子:缓存

package main

import (
	"fmt"
)

func main() {
	sscanfln()
}

func sscanfln() {
	var a string
	str := "12345"
	fmt.Sscanf(str, "%s", &a)
	fmt.Println("this is Sscanf input:", a)
	var b int
	str = "12345 333"
	fmt.Sscan(str, &a, &b)
	fmt.Println("this is Sscan input:", a, b)
	fmt.Sscanln(str, &a, &b)
	fmt.Println("this is Sscanln input:", a, b)
}

// go run main.go
// this is Sscanf input: 12345
// this is Sscan input: 12345 333
// this is Sscanln input: 12345 333
复制代码

格式化输出:函数

fmt.Printlf(format string, a ...interface{})
fmt.Print(a ...interface{})
fmt.Println(a ...interface{})
复制代码

格式化并返回字符串性能

fmt.Sprintlf(format string, a ...interface{})
fmt.Sprint(a ...interface{})
fmt.Sprintln(a ...interface{})
复制代码

格式化输入输出原理

终端实际上是一个文件,跟终端相关的实例都定义在os包里面,主要有:ui

os.Stdin 标准输入的文件实例,类型为*File
os.Stdout 标准输出的文件实例,类型为*File
os.Stderr 标准错误输出的文件实例,类型为*File
复制代码

咱们能够看看os包里面的源码,能够看到这三项分别对于了终端的三个操做。this

var (
	Stdin  = NewFile(uintptr(syscall.Stdin), "/dev/stdin")
	Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")
	Stderr = NewFile(uintptr(syscall.Stderr), "/dev/stderr")
)
复制代码

在go中全部的输入输出都是封装os包的,好比咱们经常使用的fmt.Println(),就是os.Stdout封装来进行输出。spa

func Println(a ...interface{}) (n int, err error) {
	return Fprintln(os.Stdout, a...)
}
复制代码

由于这三项都是文件类型,因此咱们也可使用文件来操做终端。好比终端读取就可使用命令行

Fiel.Read(b []byte)
复制代码

终端输出:

File.Write(b []byte)
File.WriteString(str string)
复制代码

例子:

package main

import (
	"os"
)

func main() {
	var buf [16]byte
	os.Stdin.Read(buf[:])
	// fmt.Println(string(buf[:]))
	os.Stdout.WriteString(string(buf[:]))
}

//go run main.go
//hello
//hello
复制代码

既然终端的操做类型是File,那么咱们也能够直接使用文件格式来进行格式化输入

//从文件格式化输入,空格做为分隔符,占位符和格式化输出一致
fmt.Fscanf(r io.Reader, format string, a ...interface{})
//从文件获取用户输入,存储在Scan的参数里,空格和换行符做为分隔符
fmt.Fscan(r io.Reader, a ...interface{})
//从文件获取用户输入,存储在Scanln的参数里,空格做为分隔符,遇到换行符结束
fmt.Fscanln(r io.Reader, a ...interface{})
fmt.Fprintln(w io.Writer, a ...interface{})
复制代码

这个跟以前的Scan而已少了一层封装,就很少作赘述了。

bufio读取带空格的字符串

文件自己的读取,性能是很是差的。因此咱们再文件读取的时候加上一层缓存,能够提高文件读取时的性能。 在go中,是经过bufio来进行缓存读写,以前咱们的终端也说了是File,因此咱们也可使用bufio来读取。

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	var str string
	reader := bufio.NewReader(os.Stdin)
	fmt.Println("Please input:")
	str, err := reader.ReadString('\n')
	if err == nil {
		fmt.Println(str)
	}
}

//go run main.go
//Please input:
//this is hello golang
//this is hello golang
复制代码

命令行参数处理

命令行参数都在os.Args切片里面,若是用户经过命令行传递参数,那么参数就被存在os.Args,os.Args第0个是文件名。

package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Println("args[0]:", os.Args[0])
	if len(os.Args) > 1 {
		for index, v := range os.Args {
			if index == 0 {
				continue
			}
			fmt.Printf("args[%d]: %s\n", index, v)
		}
	}

}

// 参数之间使用空格来进行分隔。
复制代码

使用flag包来写命令行参数应用:

package main

import (
	"flag"
	"fmt"
)

func main() {
	var aoo string
	flag.StringVar(&aoo, "a", "A", "a is name")
	flag.Parse()

	fmt.Println(aoo)
}
// go run main.go -a "hello"
复制代码

也有比较好的三方库对命令行进行了很好的封装,github.com/urfave/cli

相关文章
相关标签/搜索