Go语言格式化输入输出
1.格式化输入
1.从终端获取用户输入
1.fmt.Scanf(format string, a ...interface{}):格式化输入,空格作为分隔符,占位符(%s %d %f)和格式化输出一致
- 1.单行读入
package main
import "fmt"
func main() {
var a int
var b string
var c float64
fmt.Scanf("%d%s%f", &a, &b, &c)
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c)
}
10 hello 9.8345
a=10 b=hello c=9.83
Process finished with exit code 0
- 2.多行读入
package main
import "fmt"
func main() {
var a int
var b string
var c float64
/*
// 在命令行输入时会有问题(goland編輯器没问题)
fmt.Scanf("%d", &a) // 当输入1后需要回车才能输入下一个值,但是Scanf是以回车作为结束符,所以最终只能接收到第一个输入的值
fmt.Scanf("%s", &b)
fmt.Scanf("%f", &c)
1
hello
a=1 b= c=0.00
*/
// 手动处理\n换行,告知编译器将\n作为输入的结束
fmt.Scanf("%d\n", &a) // 或者 fmt.Scanf("%d\r", &a)
fmt.Scanf("%s\n", &b)
fmt.Scanf("%f\n", &c)
/*
1
hello
3.45
a=1 b=hello c=3.45
*/
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c)
}
- 3.固定文本输入
package main
import "fmt"
func main() {
var a int
var b string
var c float64
/*
测试发现有标点符号就会出现异常,找不到第三个值,不知道什么原因
count, err := fmt.Scanf("我今年%d岁了,我的名字是%s,我考了%f分", &a, &b, &c)
我今年22岁了,我的名字是sfd,我考了98.4分
input does not match format
a=22 b=sfd,我考了98.4分 c=0.00
*/
count, err := fmt.Scanf("我今年%d岁了 我的名字是%s 我考了%f分", &a, &b, &c)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(count)
}
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c)
}
/*
没有按照固定格式文本输入(失败)
22 lucy 87.9
input does not match format
a=0 b= c=0.00
按照固定文本输入(成功)
我今年22岁了 我的名字是lucy 我考了89.9分
3
a=22 b=lucy c=89.90
修改文本部分信息(失败)
我今年22岁了 我的名字是lucy 我这次考了89.9分
input does not match format
a=22 b=lucy c=0.00
*/
- 4.注意:Scanf没有办法读取一行数据,如果数据中有空格的话,Scanf默认将空格作为分隔符,可以使用
bufio实现
2.fmt.Scan(a ...interface{}):从终端获取用户输入,存储在Scan中的参数里,空格和换行符作为分隔符。两个返回值:count:用户输入了几个值,err: 用户输入错误,提示错误信息
- 1.单行读入
func main() {
var a int
var b string
var c float64
fmt.Scan(&a, &b, &c)
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c)
}
/*
一行输入
1 hello 3.45
a=1 b=hello c=3.45
换行输入
1
a
3.45
a=1 b=a c=3.45
*/
- 2.多行读入
package main
import "fmt"
func main() {
var a int
var b string
var c float64
fmt.Scan(&a)
fmt.Scan(&b)
fmt.Scan(&c)
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c)
}
/*
1
hello
3.4
a=1 b=hello c=3.40
*/
- 3.提示:要求如果要输入两个值,必须输入两个,如果是三个值,就必须是三个。否则会一直等待,不会执行下面的程序
3.fmt.Scanln(a ...interface{}):从终端获取用户输入,存储在Scanln中的参数里,空格作为分隔符,遇到换行符结束。
- 1.单行读入
func main() {
var a int
var b string
var c float64
fmt.Scan(&a, &b, &c)
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c)
}
/*
只能一行输入
1 hello 3.45
a=1 b=hello c=3.45
*/
- 2.多行读入
package main
import "fmt"
func main() {
var a int
var b string
var c float64
fmt.Scan(&a)
fmt.Scan(&b)
fmt.Scan(&c)
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c)
}
/*
1
hello
3.4
a=1 b=hello c=3.40
*/
- 3.单行输入只要回车就结束,多行输入回车就跳过,使用零值,如果输入值和接收值不匹配,缺少的会以接收值类型的零值填充,多余的忽略。
4.区别
-
fmt.Scanf如果有固定格式,就必须遵守,换行被作为结束符,如果输入不够直接换行,未输入的值就使用接收类型的零值 -
fmt.Scan要求 如果要输入两个值,必须输入两个,如果是三个值,就必须是三个。否则他会一直等待,不会执行下面的程序。 -
fmt.Scanln没有这个强制的要求,如果要求我们输入两个值,但是我们只输入一个值,我们回车之后就阔以直接执行程序,但是会报错,我们可以判断返回值err,会报错值为输入。这就是他们两个的不同。 -
Scan必须等待所要求的值输入完成才能执行程序,但是Scanln不管输入的数据是否完成,只要回车就直接执行。
2.从字符串中获取输入
1.fmt.Sscanf(str, format string, a ...interface{}):格式化输入,空格作为分隔符,占位符和格式化输出一致
package main
import "fmt"
func main() {
var a int
var b string
var c float64
str := "88hello 8.8"
fmt.Sscanf(str, "%d%s%f", &a, &b, &c)
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c) // a=88 b=hello c=8.80
}
2.fmt.Sscan(str strinf, a ...interface{}):从终端获取用户输入,存储在Scnaln中的参数里,空格和换行符作为分隔符
package main
import "fmt"
func main() {
var a int
var b string
var c float64
str := "88hello\n8.8"
fmt.Sscan(str, &a, &b, &c)
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c) // a=88 b=hello c=8.80
}
3.fmt.Sscanln(str strinf, a ...interface{}):从终端获取用户输入,存储在Scnaln中的参数里,空格作为分隔符,遇到换行符\n结束
// ln:line
package main
import "fmt"
func main() {
var a int
var b string
var c float64
/*
str := "88hello8.8"
fmt.Sscanln(str, &a, &b, &c)
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c) // a=88 b=hello8.8 c=0.00
*/
/*
str := "88hello\n8.8"
fmt.Sscanln(str, &a, &b, &c)
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c) // a=88 b=hello c=0.00
*/
str := "88hello 8.8"
fmt.Sscanln(str, &a, &b, &c)
fmt.Printf("a=%d b=%s c=%.2f\n", a, b, c) // a=88 b=hello c=8.80
}
2.格式化输出
1.输出到终端
1.fmt.Printf(format string, a ...interface{}):格式化输出到终端
2.fmt.Println(a ...interface{}):把零个或多个变量打印到终端,并换行
3.fmt.Print(a ...interface{}):把零个或多个变量打印到终端,不换行
2.输出到字符串(格式化后返回一个字符串)
1.fmt.Sprintf(format string, a ...interface{}):格式化并返回字符串
package main
import "fmt"
func main() {
const name, age, score = "Kim", 22, 89.7
// Kim今年22岁了考试考了89.70分
ret := fmt.Sprintf("%s今年%d岁了考试考了%.2f分", name, age, score)
fmt.Println(ret)
}
2.fmt.Sprintln(a ...interface{}):把零个或多个变量按空格进行格式化并换行,返回字符串
package main
import "fmt"
func main() {
const name, age, score = "Kim", 22, 89.7
ret := fmt.Sprintln(name, "今年", age, "岁", "这次考试得了", score, "分.")
// 自动以空格进行分割
fmt.Println(ret) // Kim 今年 22 岁 这次考试得了 89.7 分.
}
3.fmt.Sprint(a ...interface{}):把零个或多个变量按空格进行格式化
package main
import (
"fmt"
)
func main() {
const name, age, score = "Kim", 22, 89.7
ret := fmt.Sprint(name, " 今年 ", age, " 岁 ", "这次考试得了 ", score, " 分.\n")
fmt.Println(ret) // Kim 今年 22 岁 这次考试得了 89.7 分.
}
3.终端输入输出背后的原理
1.终端其实是一个文件
os.Stdin:标准输入的文件实例,类型为*Fileos.Stdout:标准输出的文件实例,类型为*Fileos.Stderr:标准错误输出的文件实例,类型为*File
2.以文件的方式操做终端
1.终端读取
File.Read(b []byte)
package main
import (
"fmt"
"os"
)
func main() {
buf := [16]byte{}
os.Stdin.Read(buf[:])
fmt.Println(string(buf[:]))
}
/*
this is a test
this is a test
*/
2.终端输出
File.Write[b []byte]File.WriteSting(str string)
package main
import (
"os"
)
func main() {
buf := [16]byte{}
os.Stdin.Read(buf[:])
os.Stdout.WriteString(string(buf[:]))
// os.Stdout.Write(buf[:])
}
/*
this is a test
this is a test
*/
4.从文件中获取输入输出
1.从文件中获取用户输入
- 1.
fmt.Fscanf(file, format string, a ...interface{}):从文件格式化输入,空格作为分隔符,占位符和格式化输出一致
package main
import (
"fmt"
"os"
)
func main() {
var a int
var b string
var c float64
fmt.Fscanf(os.Stdin, "%d%s%f", &a, &b, &c)
fmt.Println(a, b, c)
}
/*
10 a 29.2
10 a 29.2
*/
package main
import (
"fmt"
"os"
)
func main() {
var a int
var b string
var c float64
// 测试一直获取不到第三个参数输入的值
fmt.Fscanf(os.Stdin, "%d岁的%s考了%d分", &a, &b, &c)
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
/*
10 xiaohong 23.9
10
0
12岁的小宏考了67.5分
12
小宏考了67.5分
0
12岁的 小宏 考了67.5分
12
小宏
0
12岁的 小宏 考了 67.5 分
12
小宏
0
*/
- 2.
fmt.Fscan(file, a ...interface{}):从文件获取用户输入,存储在Scanln中的参数里,空格和换行符作为分隔符
package main
import (
"fmt"
"os"
)
func main() {
var a int
var b string
var c float64
fmt.Fscan(os.Stdin, &a, &b, &c)
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
/*
22 小亮 76.4
22
小亮
76.4
*/
- 3.
fmt.Fsacnln(file, a ...interface{}):从文件获取用户输入,存储在Scanln中的参数里,空格作为分隔符,遇到换行符结束
2.格式化输出到文件中
- 1.
fmt.Fpcanf(file, format string, a ...interface{}):格式化输出,并写入到文件中
package main
import (
"fmt"
"os"
)
func main() {
var a int
var b string
var c float64
fmt.Fscanln(os.Stdin, &a, &b, &c)
fmt.Fprintf(os.Stdout, "%d岁的%s考了%.2f分", a, b, c)
}
/*
22 小亮 89.3
22岁的小亮考了89.30分
*/
- 2.
fmt.Fpcan(file, a ...interface{}):把零个或多个变量写入到文件中,并换行
package main
import (
"fmt"
"os"
)
func main() {
var a int
var b string
var c float64
fmt.Fscanln(os.Stdin, &a, &b, &c)
fmt.Fprint(os.Stdout, a, "岁的", b, "考了", c, "分")
}
/*
22 小亮 89
22岁的小亮考了89分
*/
- 3.
fmt.Fpacnln(file, a ...interface{}):把零个或多个变量写入到文件中
package main
import (
"fmt"
"os"
)
func main() {
var a int
var b string
var c float64
fmt.Fscanln(os.Stdin, &a, &b, &c)
fmt.Fprintln(os.Stdout, a)
fmt.Fprintln(os.Stdout, b)
fmt.Fprintln(os.Stdout, c)
}
/*
22 小亮 89.2
22
小亮
89.2
Process finished with exit code 0
*/
5.带缓冲区的读写
- 实现终端读取一整行数据(数据带空格)
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
reader := bufio.NewReader(os.Stdin)
str, _ := reader.ReadString('\n')
fmt.Println(str)
}
/*
this is a test
this is a test
*/
6.命令行参数的处理
1.os.Args命令行参数的切片
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]=%v\n", index, v)
}
}
}
/*
>>> go run main.go a b "c d"
args[0]= /xxx/xxx/main.exe
args[1]=a
args[2]=b
args[3]=c d
*/
2.使用flag包获取命令行参数
flag.IntVar(&length, "l", 16, "-l 生成密码的长度")&length:用户真实输入的值l:参数名称16:默认值-l xxx:参数说明
package main
import (
"flag"
"fmt"
)
var recusive bool
var test string
var level int
func init() {
// 布尔类型只要参数指定了就可以了,不需要写 -r true
flag.BoolVar(&recusive, "r", false, "这是一个布尔值")
flag.StringVar(&test, "t", "我是默认值", "这是一个字符串的值")
flag.IntVar(&level, "l", 1, "整型,级别信息")
flag.Parse() // 解析命令行参数
}
func main() {
fmt.Printf("recusive: %v\n", recusive)
fmt.Printf("test: %v\n", test)
fmt.Printf("level: %v\n", level)
}
/*
>>> go run main.go -r -t 姚明 -l 2
recusive: true
test: 姚明
level: 2
*/
3.urfave/cli包的使用
- 1.获取包
go get github.com/urfave/cli
- 2.编码
package main
import (
"fmt"
"github.com/urfave/cli"
"os"
)
func main() {
var language string
var recusive bool
app := cli.NewApp()
app.Name = "cli" // 工具名称,可以使用 --help查看
app.Flags = []cli.Flag{
cli.StringFlag{
Name: "lang, l",
Usage: "language for the greeting", // 描述
EnvVar: "",
FilePath: "",
Required: false,
Hidden: false,
TakesFile: false,
Value: "english",
Destination: &language, // 接收命令行输入值的变量
},
cli.BoolFlag{
Name: "recusive, r",
Usage: "recusive for the greeting",
EnvVar: "",
FilePath: "",
Required: false,
Hidden: false,
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", language)
return nil
}
app.Run(os.Args)
}
- 3.查看帮助文档
>>> go run main.go --help
NAME:
cli - A new cli application
USAGE:
main.exe [global options] command [command options] [arguments...]
COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--lang value, -l value language for the greeting (default: "english")
--recusive, -r recusive for the greeting
--help, -h show help
- 4.使用
>>> go run main.go
recusive is false
language is english
>>> go run main.go -l chinese
recusive is false
language is chinese
>>> go run main.go -l chinese -r
recusive is true
language is chinese

浙公网安备 33010602011771号