Go——fmt包详解

fmt包是Go语言中用于格式化输入输出的关键包,包括Printf、Scanf等函数,支持各种格式控制,如%v,%t,%d等。这些函数用于向标准输出、文件或从标准输入、字符串进行格式化数据的读写。文章详细列举了不同函数的用法和示例,展示了如何进行格式化输出和输入操作。

fmt包

fmt包实现了格式化I/O。主要分为向外输出内容和获取输入内容两大部分。

函数列表:

func Printf(format string, a ...interface{}) (n int, err error)
func Print(a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)
func Sprintf(format string, a ...interface{}) string
func Sprint(a ...interface{}) string
func Sprintln(a ...interface{}) string
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
func Fprint(w io.Writer, a ...interface{}) (n int, err error)
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
func Scanf(format string, a ...interface{}) (n int, err error)
func Scan(a ...interface{}) (n int, err error)
func Scanln(a ...interface{}) (n int, err error)
func Sscanf(str string, format string, a ...interface{}) (n int, err error)
func Sscan(str string, a ...interface{}) (n int, err error)
func Sscanln(str string, a ...interface{}) (n int, err error)
func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
func Fscan(r io.Reader, a ...interface{}) (n int, err error)
func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
func Errorf(format string, a ...interface{}) error

format说明

Go 语言中的fmt包含有格式化输入输出的函数,类似于C语言的printf和scanf。格式字符串的规则来源于C但更简单更好用。

在 fmt 包中,有三种标准输出的打印语句:

  • Printf 可以给定输出格式的打印语句
    • Printf(“格式化串定义”,变量列表)
    • 格式化串定义:即format字符串
    • 变量列表: 可以是任意类型的值变量列表,系统实现的是一通用接口函数
  • Print 这个函数不需要format字符串,等价于对每一个参数设置为%v
  • Println 等价于Print语句,但输出时会在参数之间加上空格并在输出结束后换行
示例1
// %v  基本格式的值
// %+v 当输出结构体时,扩展标志添加成员的名字。
// %#v 值的Go语法表示。
func main() {
	t := &T{7, -2.35, "abc\tdef"}
	fmt.Printf("No01:%v\n", t)  //No01:&{7 -2.35 abc      def}
	fmt.Printf("No02:%+v\n", t) //No02:&{a:7 b:-2.35 c:abc        def}
	fmt.Printf("No03:%#v\n", t) //No03:&main.T{a:7, b:-2.35, c:"abc\tdef"}
	fmt.Printf("No04:%#v\n", timeZone) //No04:map[string]int{"EST":-18000, "CST":-21600, "MST":-25200, "PST":-28800, "UTC":0}
}

var timeZone = map[string]int{
	"UTC": 0 * 60 * 60,
	"EST": -5 * 60 * 60,
	"CST": -6 * 60 * 60,
	"MST": -7 * 60 * 60,
	"PST": -8 * 60 * 60,
}

type T struct {
	a int
	b float32
	c string
}
示例2
// 测试和说明:
// %t 值的true和false
// %T 值的类型在Go语言中的表示
// %% 打印一个 %
// %q 给打印的字串自动加引号
func main() {
	var Yes bool //bool 变量自动初始化为 false
	fmt.Printf("No01:%t\n", Yes) //No01:false
	fmt.Printf("No02:%T\n", Yes) //No02:bool
	fmt.Printf("No03:%%\n") //No03:%
	fmt.Printf("No04:%q\n", "自动加引号") //No04:"自动加引号"
}
示例3
// 整数部分
// %b 二进制表示
// %c 数值对应的Unicode编码字符
// %d 十进制表示
// %o 八进制表示
// %x 十六进制表示,使用a-f
// %X 十六进制表示,使用A-F
// %U Unicode格式: U+1234,等价于"U+%04X"
// %q 单引号
func main() {
	fmt.Printf("No01:%b\n", 888) //No01:1101111000
	fmt.Printf("No02:%c\n", '太') //No02:太
	fmt.Printf("No03:%d\n", 888) //No03:888
	fmt.Printf("No04:%o\n", 888) //No04:1570
	fmt.Printf("No05:%x\n", 888) //No05:378
	fmt.Printf("No06:%X\n", 888) //No06:378
	fmt.Printf("No07:%U\n", 888) //No07:U+0378
	fmt.Printf("No08:%q\n", 88) //No08:'X'
}
示例4
// 浮点数:
// %b 无小数部分、两位指数的科学计数法,和strconv.FormatFloat的'b'转换格式一致。
// %e 科学计数法,举例:-1234.456e+78
// %E 科学计数法,举例:-1234.456E+78
// %f 有小数部分,但无指数部分,举例:123.456
// %g 根据实际情况采用%e或%f格式(以获得更简洁的输出)
// %G 根据实际情况采用%E或%f格式(以获得更简洁的输出)
func main() {
	fmt.Printf("No01:%b\n", 888.66) //No01:7816736025115361p-43
	fmt.Printf("No02:%e\n", 888.66) //No02:8.886600e+02
	fmt.Printf("No03:%E\n", 888.66) //No03:8.886600E+02
	fmt.Printf("No04:%f\n", 888.66) //No04:888.660000
	fmt.Printf("No05:%g\n", 888.33) //No05:888.33
	fmt.Printf("No06:%g\n", 99999999.33) //No06:9.999999933e+07
	fmt.Printf("No07:%G\n", 888.33) //No07:888.33
	fmt.Printf("No08:%G\n", 99999999.33) //No08:9.999999933E+07 
}
示例5
// "No01:%.*d",10,123: 打印整数,并保证10为长度,关键是长度运行时动态传入
// "No02:%6.*f",2,888.666: 打印浮点数,并保证两位小数,关键是小数位运行时动态传入
func main() {
	fmt.Printf("No01:%.*d\n",10,123) //No01:0000000123
	fmt.Printf("No02:%6.*f\n",2,888.666) //No02:888.67
}
字符串和byte切片类型说明
  • %s 直接输出字符串或者[]byte
  • %q 双引号括起来的字符串
  • %x 每个字节用两字符十六进制数表示(使用小写a-f)
  • %X 每个字节用两字符十六进制数表示(使用大写A-F)
指针类型说明
%p 0x开头的十六进制数表示
木有'u'标志。如果是无类型整数,自然会打印无类型格式。类似的,没有必要去区分操作数的大小(int8, int64)。
宽度和精度格式化控制是指的Unicode编码字符的数量(不同于C的printf,它的这两个因子指的是字节的数量。)两者均可以使用'*'号取代(任一个或两个都),此时它们的值将被紧接着的参数控制,这个操作数必须是整型。
对于数字,宽度设置总长度,精度设置小数部分长度。例如,格式%6.2f 输出123.45。
对于字符串,宽度是输出字符数目的最低数量,如果不足会用空格填充。精度是输出字符数目的最大数量,超过则会截断。
其他符号说明
+ 总是输出数值的正负号;对%q(%+q)将保证纯ASCII码输出
- 用空格在右侧填充空缺而不是默认的左侧。
# 切换格式:在八进制前加0(%#o),十六进制前加0x(%#x)0X(%#X);废除指针的0x(%#p);
对%q (%#q)如果可能的话输出一个无修饰的字符串;
对%U(%#U)如果对应数值是可打印字符输出该字符。
' ' 对数字(% d)空格会留一个空格在数字前并忽略数字的正负号;
对切片和字符串(% x, % X)会以16进制输出。
0 用前置0代替空格填补空缺。
补充说明
每一个类似Printf的函数,都会有一个同样的Print函数,此函数不需要format字符串,等价于对每一个参数设置为%v。另一个变体Println会在参数之间加上空格并在输出结束后换行。
如果参数是一个接口值,将使用内在的具体实现的值,而不是接口本身,%v参数不会被使用。如下:
var i interface{} = 23
fmt.Printf("%v\n", i)
将输出23。
如果参数实现了Formatter接口,该接口可用来更好的控制格式化。
如果格式(标志对Println等是隐含的%v)是专用于字符串的(%s %q %v %x %X),还提供了如下两个规则:
1. 如果一个参数实现了error接口,Error方法会用来将目标转化为字符串,随后将被按给出的要求格式化。
2. 如果参数提供了String方法,这个方法将被用来将目标转换为字符串,然后将按给出的格式标志格式化。
为了避免有可能的递归循环,例如:
type X string
func (x X) String() string { return Sprintf("<%s>", x) }
会在递归循环前转换值:
func (x X) String() string { return Sprintf("<%s>", string(x)) }
错误的格式:
如果提供了一个错误的格式标志,例如给一个字符串提供了%d标志,生成的字符串将包含对该问题的描述,如下面的例子:
错误或未知的格式标志: %!verb(type=value)
Printf("%d", hi): %!d(string=hi)
太多参数: %!(EXTRA type=value)
Printf("hi", "guys"): hi%!(EXTRA string=guys)
缺少参数: %!verb(MISSING)
Printf("hi%d"): hi %!d(MISSING)
使用非整数提供宽度和精度: %!(BADWIDTH) or %!(BADPREC)
Printf("%*s", 4.5, "hi"): %!(BADWIDTH)hi
Printf("%.*s", 4.5, "hi"): %!(BADPREC)hi
所有的错误都使用"%!"起始,(紧随单字符的格式标志)以括号包围的错误描述结束。
输入
一系列类似的函数读取格式化的文本,生成值。Scan,Scanf和Scanln从os.Stdin读取;Fscan,Fscanf和Fscanln 从特定的io.Reader读取;Sscan,Sscanf和Sscanln 从字符串读取;Scanln,Fscanln和Sscanln在换行时结束读取,并要求数据连续出现;Scanf,Fscanf和Sscanf会读取一整行以匹配格式字符串;其他的函数将换行看着空格。
Scanf, Fscanf, and Sscanf根据格式字符串解析数据,类似于Printf。例如,%x将读取一个十六进制数,%v将读取值的默认表示。
格式行为类似于Printf,但有如下例外:
%p没有提供
%T没有提供
%e %E %f %F %g %G是等价的,都可以读取任何浮点数或者复合数(非复数,指科学计数法表示的带指数的数)
%s 和 %v字符串使用这两个格式读取时会因为空格而结束
不设格式或者使用%v读取整数时,如果前缀为0(八进制)0x(十六进制),将按对应进制读取。
宽度在输入中被解释(%5s意思是最多从输入读取5个字符赋值给一个字符串),但输入系列函数没有解释精度的语法(木有%5.2f,只有%5f)。
输入系列函数中的格式字符串,所有非空的空白字符(除了换行符之外),无论在输入里还是格式字符串里,都等价于1个空白字符。格式字符串必须匹配输入的文本,如果不匹配将停止读取数据并返回函数已经赋值的参数的数量。
所有的scan系列函数,如果参数包含Scan方法(或者说实现了Scanner接口),该参数将使用该方法读取文本。另外,如果被填写的参数的数量少于提供的参数的数量,将返回一个错误。
所有要被输入的参数都应该是基础类型或者实现了Scanner接口的数据类型的指针。
注意:Fscan等函数可以从输入略过一些字符读取需要的字符并返回,这就意味着一个循环的读取程序可能会跳过输入的部分数据。当数据间没有空白时就会导致出现问题。如果读取这提供给Fscan系列函数ReadRune 方法,这个方法可以用来读取字符。如果读取者还提供了UnreadRune 方法,该方法将被用来保存字符以使成功的调用不会丢失数据。为了给一个没有这些功能的读取者添加这俩方法,使用bufio.NewReader。

1、Print系列函数

用于标准输出

1.1 func Print(a …interface{}) (n int, err error)
  • 参数列表
    • a… 值变量列表
  • 返回值:
    • 返回打印字符数 n
    • 返回error
  • 功能说明:这个函数主要是用来根据系统默认格式字符串和参数表生成一个打印字符串
1.2 func Printf(format string, a …interface{}) (n int, err error)
  • 参数列表
    • format 打印的格式说明
    • a… 值变量列表
  • 返回值:
    • 返回打印字符数 n
    • 返回error
  • 功能说明:这个函数主要是用来根据说明格式字符串和参数表生成一个打印字符串
1.3 func Println(a …interface{}) (n int, err error)
  • 参数列表
    • a… 值变量列表
  • 返回值:
    • 返回打印字符数 n
    • 返回error
  • 功能说明:这个函数主要是用来根据系统默认格式字符串和参数表生成一个打印字符串并加换行
func main() {
	fmt.Print("默认格式打印!") //默认格式打印!

	fmt.Printf("Format:%s\n", "格式打印!") //Format:格式打印!

	fmt.Println("默认格式打印,有换行啊!") //默认格式打印,有换行啊!
}

2、Scan系列函数

用于标准输入

2.1 func Scan(a …interface{}) (n int, err error)
  • 参数列表
    • a… 值变量列表
  • 返回值:
    • 返回成功读取的参数的数量 n
    • 返回error
  • 功能说明:这个函数主要是从标准输入读取文本,将空白分割的连续数据顺序存入参数里。换行视同空白。它返回成功读取的参数的数量。如果少于提供的参数的数量,返回值err将报告原因。
2.2 func Scanf(format string, a …interface{}) (n int, err error)
  • 参数列表
    • format 输入格式说明
    • a… 值变量列表
  • 返回值:
    • 返回输入字符数 n
    • 返回error
  • 功能说明:这个函数主要是从标准输入读取文本,根据格式字符串顺序将数据存入参数中,它返回成功解析并存入的参数的数量
func Scanln(a …interface{}) (n int, err error)

2.3 参数列表
- a… 值变量列表

  • 返回值:
    • 返回成功读取的参数的数量 n
    • 返回error
  • 功能说明:这个函数主要是从标准输入读取文本,将空白分割的连续数据顺序存入参数里。换行视同空白。它返回成功读取的参数的数量。如果少于提供的参数的数量,返回值err将报告原因。类似Scan,但会在换行符中止,并且存入最后一条后时读取位置必须有换行或者结束符。
func main() {
	var a, b, c int
	fmt.Scan(&a, &b, &c)
	fmt.Println(a, b, c)

	//注意下面的Scanf("%d,%d,%d",&a,&b,&c)中%d,%d,%d之间有逗号,
	//在输入数据时也要加逗号,如果去掉逗号,输入时就不用逗号,
	//而用空格,tab键或回车键将各个数据隔开
	fmt.Scanf("%d,%d,%d", &a, &b, &c)
	fmt.Println(a, b, c)

	fmt.Scanln(&a, &b, &c)
	fmt.Println(a, b, c)
}

3、Fprint系列函数

输出到文件指针

3.1 func Fprint(w io.Writer, a …interface{}) (n int, err error)
  • 参数列表
    • w 写入文件指针
    • a… 值变量列表
  • 返回值:
    • 返回打印字符数 n
    • 返回error
  • 功能说明:这个函数主要是用来根据默认格式字符串和参数表生成一个打印字符串并写入指定文件
3.2 func Fprintf(w io.Writer, format string, a …interface{}) (n int, err error)
  • 参数列表
    • w 写入文件指针
    • format 打印的格式说明
    • a… 值变量列表
  • 返回值:
    • 返回打印字符数 n
    • 返回error
  • 功能说明:这个函数主要是用来根据说明格式字符串和参数表生成一个打印字符串
3.3 func Fprintln(w io.Writer,a …interface{}) (n int, err error)
  • 参数列表
    • w 写入文件指针
    • a… 值变量列表
  • 返回值:
    • 返回打印字符数 n
    • 返回error
  • 功能说明:这个函数主要是用来根据默认格式字符串和参数表生成一个打印字符串并加换行写入指定文件
func main() {
	fmt.Fprint(os.Stdout, "默认格式打印!")
	file, err := os.Create("a.txt")
	if err != nil {
		err.Error()
	}
	defer file.Close()
	fmt.Fprint(file, "hello world!")

	fmt.Fprintf(os.Stdout, "Format:%s\n", "格式打印!")

	fmt.Fprintln(os.Stdout, "默认格式加换行打印!")
}

4、Fscan系列函数

从文件指针读取

4.1 func Fscan(r io.Reader, a …interface{}) (n int, err error)
  • 参数列表
    • r 输入文件指针
    • a… 值变量列表
  • 返回值:
    • 返回成功读取的参数的数量 n
    • 返回error
  • 功能说明:这个函数主要是从指定文件读取文本,将空白分割的连续数据顺序存入参数里。换行视同空白。它返回成功读取的参数的数量。如果少于提供的参数的数量,返回值err将报告原因。
4.2 func Fscanf(r io.Reader, format string, a …interface{}) (n int, err error)
  • 参数列表
    • r 输入文件指针
    • format 输入格式说明
    • a… 值变量列表
  • 返回值:
    • 返回输入字符数 n
    • 返回error
  • 功能说明:这个函数主要是从指定文件中按说明的格式读取文本,根据格式字符串顺序将数据存入参数中,它返回成功解析并存入的参数的数量
4.3 func Fscanln(r io.Reader, a …interface{}) (n int, err error)
  • 参数列表
    • r 输入文件指针
    • a… 值变量列表
  • 返回值:- 返回成功读取的参数的数量 n
    • 返回error
  • 功能说明:这个函数主要是从指定文件中读取文本,将空白分割的连续数据顺序存入参数里。换行视同空白。它返回成功读取的参数的数量。如果少于提供的参数的数量,返回值err将报告原因。类似Scan,但会在换行符中止,并且存入最后一条后时读取位置必须有换行或者结束符。
func main() {
	n, err = fmt.Fscan(os.Stdin, &a, &b, &c)
	fmt.Println(a, b, c)
	fmt.Printf("输入正确参数%v个,错误参数原因:%v", n, err)
	file, e := os.Open("a.txt")
	if e != nil {
		e.Error()
	}
	defer file.Close()
	var str string
	fmt.Fscanf(file, "%s\n", &str)
	fmt.Println(str)

	var a, b, c int
	fmt.Fscanf(os.Stdin, "%d,%d,%d", &a, &b, &c)
	fmt.Println(a, b, c)

	fmt.Fscanln(os.Stdin, &a, &b, &c)
	fmt.Println(a, b, c)
}

var (
	n, a, b, c int
	err        error
)

5、Sprint系列函数

输出为字符串

5.1 func Sprint(a …interface{}) string
  • 参数列表
    • a… 值变量列表
  • 返回值:返回打印字符串
  • 功能说明:这个函数主要是用来根据默认格式字符串和参数表生成一个打印字符串
5.2 func Sprintf(format string, a …interface{}) string
  • 参数列表
    • format 打印的格式说明
    • a… 值变量列表
  • 返回值:返回打印字符串
  • 功能说明:这个函数主要是用来根据说明格式字符串和参数表生成一个打印字符串
5.3 func Sprintln(a …interface{}) string
  • 参数列表
    • a… 值变量列表
  • 返回值:返回打印字符串
  • 功能说明:这个函数主要是用来根据默认格式字符串和参数表生成一个打印字符串并带换行
func main() {
	str1 := fmt.Sprint("默认格式打印出字符串!")
	fmt.Println(str1) //默认格式打印出字符串!

	str2 := fmt.Sprintf("Format:%s\n", "格式打印出字符串!")
	fmt.Println(str2) // Format:格式打印出字符串!

	str3 := fmt.Sprintln("默认格式打印出字符串并带换行!")
	fmt.Println(str3) //默认格式打印出字符串并带换行!
}

6、Sscan系列函数

从字符串读取

6.1 func Sscan(str string, a …interface{}) (n int, err error)
  • 参数列表
    • str 指定源字符串
    • a… 值变量列表
  • 返回值:
    • 返回成功读取的参数的数量 n
    • 返回error
  • 功能说明:这个函数主要是从指定源字符串str中读取文本,将空白分割的连续数据顺序存入参数里。换行视同空白。它返回成功读取的参数的数量。如果少于提供的参数的数量,返回值err将报告原因。
6.2 func Sscanf(str string, format string, a …interface{}) (n int, err error)
  • 参数列表
    • str 指定的源字符串
    • format 输入格式说明
    • a… 值变量列表
  • 返回值:
    • 返回输入字符数 n
    • 返回error
  • 功能说明:这个函数主要是从指定字符串str中按说明的格式读取文本,根据格式字符串顺序将数据存入参数中,它返回成功解析并存入的参数的数量
6.3 func Sscanln(str string, a …interface{}) (n int, err error)
  • 参数列表
    • str 指定源字符串
    • a… 值变量列表
  • 返回值:
    • 返回成功读取的参数的数量 n
    • 返回error
  • 功能说明:这个函数主要是从指定源字符串str中读取文本,将空白分割的连续数据顺序存入参数里。换行视同空白。它返回成功读取的参数的数量。如果少于提供的参数的数量,返回值err将报告原因。类似Scan,但会在换行符中止,并且存入最后一条后时读取位置必须有换行或者结束符。
func main() {
	str := "34  343  245"
	var a, b, c int
	fmt.Sscan(str, &a, &b, &c)
	fmt.Println(a, b, c) //34 343 245

	str = "13 23 45"
	fmt.Sscanf(str, "%d,%d,%d", &a, &b, &c)
	fmt.Println(a, b, c) //13 343 245

	str = "30  342  2415"
	fmt.Sscanln(str, &a, &b, &c)
	fmt.Println(a, b, c) //30 342 2415
}
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值