ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GO终端读取

2021-04-01 14:57:56  阅读:292  来源: 互联网

标签:oldboy 读取 fmt flag 终端 func GO main string


GO终端读取

Go语言获取标准输入

Go语言 fmt 包下有 fmt.Scan、fmt.Scanf、fmt.Scanln 三个函数,可以在程序运行过程中获取用户输入。

func Scan(a …interface{}) (n int, err error)

Scan从标准输入扫描文本,将成功读取的空白分隔的值保存进成功传递给本函数的参数。换行视为空白。返回成功扫描的条目个数和遇到的任何错误。如果读取的条目比提供的参数少,会返回一个错误报告原因。

func Scanf(format string, a …interface{}) (n int, err error)

Scanf从标准输入扫描文本,根据format 参数指定的格式将成功读取的空白分隔的值保存进成功传递给本函数的参数。返回成功扫描的条目个数和遇到的任何错误。

func Scanln(a …interface{}) (n int, err error)

Scanln类似Scan,但会在换行时才停止扫描。最后一个条目后必须有换行或者到达结束位置。

获取标准输入示例

示例一:Scan 函数应用

package main

import  "fmt"

func  main() {

fmt.Println("Please enter your firstname and lastname ")

var  firstname, lastname  string

fmt.Scan(&firstname, &lastname)

fmt.Println("hello,", firstname, "and", lastname)

}

编译后运行,在窗口中输入:
oldboy golang
输出:
hello, oldboy and golang
可以看出,go把输入的参数按空格分开后,分别赋值给了 firstname 和 lastname 。
整体运行结果(第二行是运行时用户输入的):
Please enter your firstname and lastname
oldboy golang
hello, oldboy and golang
再次运行,这次我们输入时换行输入:
Please enter your firstname and lastname
oldboy
golang
hello, oldboy and golang
在第二行、第三行 oldboy 和 golang 中间是敲了回车的,这是Scan和Scanln的区别。Scanln只要收到回车就不会继续接收输入了。

示例二:Scanf 函数应用

package main

import  "fmt"

func  main() {

fmt.Println("Please enter your names ")

var  firstname, lastname  string

fmt.Scanf("%s , %s", &firstname, &lastname)

fmt.Println("hello,", firstname, "and", lastname)

}

编译运行:
Please enter your firstname and lastname
oldboy , golang
hello, oldboy and golang
注意:
1、Scanf中间有一个逗号(,)逗号和%s间有空格,因为Scanf是用空格来区分不同的参数的。
2、输入的参数gates , jobs 格式与 Scanf 中指定的 fmt 要一致。
3、中间的逗号(,)Scanf会自动格式匹配不会添加到变量中。

示例三:Scanln 函数应用

package main

import  "fmt"

func  main() {

fmt.Println("Please enter your names ")

var  firstname, lastname  string

fmt.Scanln(&firstname, &lastname)

fmt.Println("hello,", firstname, "and", lastname)

}

编译运行:
Please enter your firstname and lastname
oldboy golang
hello, oldboy and golang
Scanln和Scan非常类似,只是Scanln只会接受一个回车,收到回车就扫描结束了。

其它类似函数
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)

功能同 fmt.Scan、fmt.Scanf、fmt.Scanln 三个函数,只不过从 r 中读取数据。
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)

功能同 fmt.Scan、fmt.Scanf、fmt.Scanln 三个函数,只不过从 str 中读取数据。

Go语言获取命令行参数

os.Args
os包提供一些函数和变量。
变量os.Args是一个字符串slice。可以理解它是一个动态容量的顺序数组s,可以通过s[i]来访问单个元素,通过s[m:n]来访问一段连续子区间,数组长度用len(s)表示。
在Go语言中,所有的索引使用半开区间,即包含第一个索引,不包含最后一个索引。
os.Args的第一个元素是os.Args[0],它是命令本身的名字;另外的元素是程序开始执行时的参数。表达式s[m:n]表示一个从第m个到第n-1个元素的slice。

package main

import (
    "fmt"
    "os"
    "strconv"
)

func main() {
    for k, v := range os.Args {
        fmt.Println("参数"+strconv.Itoa(k)+":", v)
    }
}

编译并运行,在窗口中输入:
go build main.go

./main -u oldboy -p 123456
运行结果:
参数0: ./main
参数1: -u
参数2: oldboy
参数3: -p
参数4: 123456
可以看到,命令行参数包括了程序路径本身,以及通常意义上的参数。
程序中os.Args的类型是 []string ,也就是字符串切片。所以可以在for循环的range中遍历,还可以用 len(os.Args) 来获取其数量。

flag包

Go 提供了一个 flag 包,支持基本的命令行标志解析。flag包相比单纯的通过os.Args切片分析命令行参数,提供了更强的能力,同时也是复杂的用法。

命令行解析常用函数和方法:
func Parse()

从os.Args[1:]中解析注册的flag。必须在所有flag都注册好而未访问其值时执行。未注册却使用flag -help时,会返回ErrHelp。
func Int(name string, value int, usage string) *int

Int用指定的名称、默认值、使用信息注册一个int类型flag。返回一个保存了该flag的值的指针。
func Bool(name string, value bool, usage string) *bool

Bool用指定的名称、默认值、使用信息注册一个bool类型flag。返回一个保存了该flag的值的指针。
func String(name string, value string, usage string) *string

String用指定的名称、默认值、使用信息注册一个string类型flag。返回一个保存了该flag的值的指针。
func Args() []string

返回解析之后剩下的非flag参数。(不包括命令名)
func (f *FlagSet) StringVar(p *string, name string, value string, usage string)

StringVar用指定的名称、默认值、使用信息注册一个string类型flag,并将flag的值保存到p指向的变量。
程序示例:

package main

import (
    "flag"
    "fmt"
)

var i = flag.Int("i", 0, "int类型参数")
var b = flag.Bool("b", false, "bool类型参数")
var s = flag.String("s", "", "string类型参数")

func main() {
    flag.Parse()
    fmt.Println("-i:", *i)
    fmt.Println("-b:", *b)
    fmt.Println("-s:", *s)
    fmt.Println("其他参数:", flag.Args())
}

编译并运行,在窗口中输入:
go build main.go

./main -i 100 -b -s string hi golang
运行结果:
-i: 100
-b: true
-s: string
其他参数: [hi golang]

上述代码在 flag.Prase() 之前,定义了 i、b、s 三个接受参数的变量, i、b、s 是指针类型的变量。flag.String() 方法返回的是保存日后解析出来的对应参数的值的位置,是一个已经分配好的空间,我们可以用这个指针变量来接受这个位置。
待程序重新进入main函数,执行flag.Parse()函数之后,这三个位置上就出现了我们命令行传入的参数(其实在程序初始化期就有默认值)。
后续我们可以使用 i、b、*s 来访问具体的内容。

应用示例:

package main

import (
    "flag"
    "fmt"
)

var (
    confPath string = "./oldboy.conf"
    logPath  string = "./oldboy.log"
)

func init() {
    flag.StringVar(&confPath, "conf", "./oldboy.conf", "set config file path")
    flag.StringVar(&logPath, "log", "./oldboy.log", "set log file path")
}

func main() {
    flag.Parse()
    fmt.Println("config path : ", confPath)
    fmt.Println("log path : ", logPath)
}

编译并运行,在窗口中输入:
go build main.go

./main -conf ./oldboy/go.conf -log ./oldboy/go.log
运行结果:
config path : ./oldboy/go.conf
log path : ./oldboy/go.log

注意1:如果你省略一个标志,那么这个标志的值自动的设定为他的默认值。

./main -conf ./oldboy/go.conf

运行结果:
config path : ./oldboy/go.conf
log path : ./oldboy.log

注意2:flag 包需要所有的标志出现位置参数之前(否则,这个标志将会被解析为位置参数)。
./main go -conf ./oldboy/go.conf -log ./oldboy/go.log
运行结果:
config path : ./oldboy.conf
log path : ./oldboy.log

注意3:使用 -h 或者 --help 标志来得到自动生成的这个命令行程序的帮助文本。
./main -h
运行结果:
Usage of ./main:
-conf string
​ set config file path (default “./oldboy.conf”)
-log string
​ set log file path (default “./oldboy.log”)

注意4:如果你提供一个没有使用 flag 包指定的标志,程序会输出一个错误信息,并再次显示帮助文本。
./main -what
运行结果:
flag provided but not defined: -what
Usage of ./main:
-conf string
​ set config file path (default “./oldboy.conf”)
-log string
​ set log file path (default “./oldboy.log”)

标签:oldboy,读取,fmt,flag,终端,func,GO,main,string
来源: https://blog.csdn.net/weixin_35688430/article/details/115374152

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有