Golang IO 操作

Posted 知其黑、受其白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Golang IO 操作相关的知识,希望对你有一定的参考价值。

阅读目录

1 格式化输入

从终端获取用户输入

格式化输入,空格作为分隔符,占位符和格式化输出一致。

fmt.Scanf(format string,a...interface)

从终端获取用户输入,存储在Scanln中的参数里,空格和换行符作为分隔符。

fmt.Scan(a...interface)

从终端获取用户输入,存储在Scanln中的参数里,空格作为分隔符,遇到换行符结束。

fmt.Scanln(a...interface)

fmt.Scanf

package main

import "fmt"

func testInput() 
	var a int
	var b string
	var c float32

	fmt.Scanf("%d%s%f", &a, &b, &c)
	fmt.Printf("a=%d b=%s c=%f\\n", a, b, c)


func main() 
	testInput()

PS E:\\TEXT\\test_go\\one> go run .\\main.go
33 wgchen 888888.88
a=33 b=wgchen c=888888.875000
PS E:\\TEXT\\test_go\\one>

Windows 终端输入第一个回车结束,只能获取到第一个。

fmt.Scanf("%d",&a)
fmt.Scanf("%s",&a)
fmt.Scanf("%f",&a)

\\n 的意思是直到遇到换行符为止。

fmt.Scanf("%d\\n",&a)
fmt.Scanf("%s\\n",&a)
fmt.Scanf("%f\\n",&a)

fmt.Scan

package main

import "fmt"

func testScan() 
	var a int
	var b string
	var c float32

	fmt.Scan(&a, &b, &c)
	fmt.Printf("a=%d b=%s c=%f\\n", a, b, c)


func main() 
	testScan()

PS E:\\TEXT\\test_go\\one> go run .\\main.go
12
cc
888888.88
a=12 b=cc c=888888.875000
PS E:\\TEXT\\test_go\\one>

fmt.Scanln

package main

import "fmt"

func testScanln() 
	var a int
	var b string
	var c float32

	fmt.Scanln(&a, &b, &c)
	fmt.Printf("a=%d b=%s c=%f\\n", a, b, c)


func main() 
	testScanln()

PS E:\\TEXT\\test_go\\one> go run .\\main.go
88
a=88 b= c=0.000000
PS E:\\TEXT\\test_go\\one> go run .\\main.go
88 hello 888.888
a=88 b=hello c=888.888000
PS E:\\TEXT\\test_go\\one>

2 格式化输入背后的原理


os.Stdin.Read 终端读取

package main

import (
	"fmt"
	"os"
)

func main() 
	var buf [16]byte
	os.Stdin.Read(buf[:])
	fmt.Println(string(buf[:]))

os.Stdout.WriteString 终端输出

package main

import (
	"os"
)

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

	os.Stdout.WriteString(string(buf[:]))

PS E:\\TEXT\\test_go\\one> go run .\\main.go
this is hahahahah
this is hahahaha
PS E:\\TEXT\\test_go\\one>

fmt.Fscanf 文件格式输入

package main

import (
	"fmt"
	"os"
)

func main() 
	var a int
	var b string
	var c float32
	fmt.Fscanf(os.Stdin, "%d%s%f", &a, &b, &c)
	// fmt.Scanf("%d%s%f", &a, &b, &c)
	fmt.Println(a, b, c)

PS E:\\TEXT\\test_go\\one> go run .\\main.go
1 a 3.3
PS E:\\TEXT\\test_go\\one> go run .\\main.go
1 a 3.3
1 a 3.3
PS E:\\TEXT\\test_go\\one>

fmt.Fprintln 格式化输出到文件中

package main

import (
	"fmt"
	"os"
)

func main() 
	var a int
	var b string
	var c float32
	fmt.Fscanf(os.Stdin, "%d%s%f", &a, &b, &c)
	fmt.Fprintln(os.Stdout, a, b, c)

PS E:\\TEXT\\test_go\\one> go run .\\main.go
66 aa 33.33
66 aa 33.33
PS E:\\TEXT\\test_go\\one>

3 bufio 包的使用

带缓冲区的文件读写。

package main

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

var inputReader *bufio.Reader
var input string
var err error

func main() 
	inputReader = bufio.NewReader(os.Stdin)
	fmt.Println("Please enter some input:")

	input, err = inputReader.ReadString('\\n')
	if err == nil 
		fmt.Printf("The input was:%s\\n", input)
	

PS E:\\TEXT\\test_go\\one> go run .\\main.go
Please enter some input:
wgchen
The input was:wgchen

PS E:\\TEXT\\test_go\\one>

4 命令行参数处理和 urfave/cli 使用

os.Args 命令行参数的切片。

package main

import (
	"fmt"
	"os"
)

func main() 
	// who := "Alice"
	// if len(os.Args) > 1 
	// 	who += strings.Join(os.Args[1:], " ")
	// 
	// fmt.Println("Good Morning", who)

	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]=%v\\n", index, v)
		
	


PS E:\\TEXT\\test_go\\one> go run .\\main.go  first secnd
args[0]= C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\go-build893513147\\b001\\exe\\main.exe
args[1]=first
args[2]=secnd
PS E:\\TEXT\\test_go\\one>

命令行参数处理

flag 包命令行选项的使用。

package main

import (
	"flag"
	"fmt"
)

var recusive bool
var test string
var level int

func init() 
	flag.BoolVar(&recusive, "r", false, "recusive xxx")
	flag.StringVar(&test, "t", "default string", "string option")
	flag.IntVar(&level, "l", 1, "level of xxxxx")
	flag.Parse()


func main() 
	fmt.Printf("recusive:%v\\n", recusive)
	fmt.Printf("test:%v\\n", test)
	fmt.Printf("level:%v\\n", level)

PS E:\\TEXT\\test_go\\one> go run .\\main.go -r -t hello -l 88888888
recusive:true
test:hello
level:88888888
PS E:\\TEXT\\test_go\\one>

urfave/cli 使用

安装 urfave/cli 包,属于命令行框架。

PS E:\\TEXT\\test_go\\one> go get github.com/urfave/cli
go: downloading github.com/urfave/cli v1.22.12
go: added github.com/cpuguy83/go-md2man/v2 v2.0.2
go: added github.com/russross/blackfriday/v2 v2.1.0
go: added github.com/urfave/cli v1.22.12
PS E:\\TEXT\\test_go\\one>
package main

import (
	"fmt"
	"os"

	"github.com/urfave/cli"
)

func main() 
	app := cli.NewApp()
	app.Name = "greet"
	app.Usage = "fight the loneliness!"
	app.Action = func(c *cli.Context) error 
		fmt.Println("hello friend!")
		return nil
	
	app.Run(os.Args)

PS E:\\TEXT\\test_go\\one> go run .\\main.go
hello friend!
PS E:\\TEXT\\test_go\\one>

获取命令行参数

package main

import (
	"fmt"
	"os"

	"github.com/urfave/cli"
)

func main() 
	app := cli.NewApp()

	app.Action = func(c *cli.Context) error 
		var cmd string
		if c.NArg() > 0 
			cmd = c.Args()[0]
		
		fmt.Println("hello friend! cmd", cmd)
		return nil
	
	app.Run(os.Args)

PS E:\\TEXT\\test_go\\one> go run .\\main.go  baidu.com
hello friend! cmd baidu.com
PS E:\\TEXT\\test_go\\one>

使用 cli 框架

package main

import (
	"fmt"
	"os"

	"github.com/urfave/cli"
)

func main() 
	var language string
	var recusive bool
	app := cli.NewApp()
	app.Flags = []cli.Flag
		cli.StringFlag
			Name:        "lang, l",
			Value:       "english",
			Usage:       "select language",
			Destination: &language,
		,
		cli.BoolFlag
			Name:        "recusive, r",
			Usage:       "recusive for the greeting",
			Destination: &recusive,
		,
	

	app.Action = func(c *cli.Context) error 
		var cmd string
		if c.NArg() > 0 
			cmd = c.Args()[0]
			fmt.Println("cmd is ", cmd)
		
		fmt.Println("recusive is ", recusive)
		fmt.Println("language is is ", language)
		return nil
	
	app.Run(os.Args)

PS E:\\TEXT\\test_go\\one> go run .\\main.go --lang chinese
recusive is  false
language is is  chinese
PS E:\\TEXT\\test_go\\one>

5 实现一个简易的计算器

实现一个简易的计算器,支持加减乘除以及带括号的计算表达式,用户从终端输入表达式,程序输出计算结果。

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/urfave/cli"
)

type Stack struct 
	data [1024]string
	top  int


// Push data to stack
func (s *Stack) Push(d string) 
	s.data[s.top] = d
	s.top++


func (s *Stack) Pop() (ret string, err error) 
	if s.top == 0 
		err = fmt.Errorf("stack is empty")
		return
	
	s.top--
	ret = s.data[s.top]
	return


func (s *Stack) Top() (ret string, err error) 
	if s.top == 0 
		err = fmt.Errorf("stack is empty")
		return
	
	ret = s.data[s.top-1]
	return


func (s *Stack) Empty() bool 
	return s.top == 0


func getInput() (string, error) 
	reader := bufio.NewReader(os.Stdin)
	return reader.ReadString('\\n')


func transPostExpress(express string) (postExpress []string, err error) 
	var opStack Stack
	var i int
LABEL:
	for i < len(express) 
		switch 
		//35+27
		case express[i] >= '0' && express[i] <= '9':
			var number []byte
			for ; i < len(express); i++ 
				if express[i] < '0' || express[i] > '9' 
					break
				
				number = append(number, express[i])
			
			//numStack.Push(string(number))
			postExpress = append(postExpress, string(number))
		case express[i] == '+' || express[i] == '-' || express[i] == '*' || express[i] == '/':
			if opStack.Empty() 
				opStack.Push(fmt.Sprintf("%c", express[i]))
				i++
				continue LABEL
			
			data, _ := opStack.Top()
			if data[0] == '(' || data[0] == ')' 
				opStack.Push(fmt.Sprintf("%c", express[i]))
				i++
				continue LABEL
			
			if (express[i] == '+' || express[i] == '-') ||
				((express[i] == '*' || express[i] == '/') && (data[0] == '*' || data[0] == '/')) 
				//numStack.Push(data)
				postExpress = append(postExpress, data)
				opStack.Pop()
				opStack.Push(fmt.Sprintf("%c", express[i]))
				i++
				continue LABEL
			
			opStack.Push(fmt.Sprintf("%c", express[i]))
			i++
		case express[i] == '(':
			opStack.Push(fmt.Sprintf("%c", express[i]))
			i++
		case express[i] == ')':
			for !opStack.Empty() 
				data, _ := opStack.Pop()
				if data[0] == '(' 
					break
				
				postExpress = append(postExpress, data)
				//numStack.Push(data)
			
			i++
		default:
			err = fmt.Errorf("invalid express:%v", express[i])
			return
		
	

	for !opStack.Empty() 
		data, _ := opStack.Pop()
		if data[0] == '#' 
			break
		

		postExpress = append(postExpress, data)
		//numStack.Push(data)
	
	return


func calc(postExpress []string) (result int64, err error) 
	var n1, n2 string
	var s Stack
	for i := 0; i < len(postExpress); i++ 
		var cur = postExpress[i]
		if cur[0] == '-' || cur[0] == '+' || cur[0] == '*' || cur[0] == '/' 
			n1, err = s.Pop()
			if err != nil 
				return
			
			n2, err = s.Pop()
			if err != nil 
				return
			

			num2, _ := strconv.Atoi(n1)
			num1,<

以上是关于Golang IO 操作的主要内容,如果未能解决你的问题,请参考以下文章

golang 初体验 - 令人惊叹的语法 - defer.1

Golang (Go语言) Mac OS X下环境搭建 环境变量配置 开发工具配置 Sublime Text 2

设置Golang的开发环境

技术分享 | Golang 1.9源码目录结构

golang的select用法

Go语言自学系列 | golang标准库io包