Go 学习笔记(46)— Go 标准库之 fmt(输入/输出格式化参数、Printf/Fprintf/Sprintf区别、Println/Fprintln/Sprintln 区别)
1. 概述
import "fmt"
fmt 包實現了類似 C 語言 printf 和 scanf 的格式化 I/O 。格式化動作( verb )源自 C 語言但更簡單。
2. Printing 格式化
2.1 通用格式
| 格式化標記 | 格式化含義 | 
|---|---|
| %v | 值的默認格式表示 | 
| %+v | 類似%v,但輸出結構體時會添加字段名 | 
| %#v | 值的類型的Go語法表示 | 
| %% | 百分號 | 
代碼示例:
package mainimport "fmt"type Person struct {Name stringAge  int
}func main() {a := 10s := "hello world"p := Person{Name: "wohu", Age: 25}c := []int{1, 2, 3, 4}fmt.Printf("p %%v is %v\n", p)   // p %v is {wohu 25}fmt.Printf("p %%+v is %+v\n", p) // p %+v is {Name:wohu Age:25}fmt.Printf("p %%#v is %#v\n", p) // p %#v is main.Person{Name:"wohu", Age:25}fmt.Printf("p type is %T\n", p)  // p type is main.Personfmt.Printf("a %%#v is %#v, a type is %T\n", a, a) // a %#v is 10, a type is intfmt.Printf("s %%#v is %#v, s type is %T\n", s, s) // s %#v is "hello world", s type is stringfmt.Printf("c %%v is %v, c type is %T\n", c, c)   // c %v is [1 2 3 4], c type is []intfmt.Printf("c %%#v is %#v, c type is %T\n", c, c) // c %#v is []int{1, 2, 3, 4}, c type is []int
}
注意當
c := []int{1, 2, 3, 4}
%v 打印的內容是 [1,2,3,4], %#v 打印的內容是 []int{1, 2, 3, 4},所以為了便于查看值類型,建議使用 %#v 。
2.2 布爾值格式
| 格式化標記 | 格式化含義 | 
|---|---|
| %t | 單詞true或false | 
代碼示例:
func main() {var a boolfmt.Printf("a %%v is %v, %%#v is %#v, %%T is %T\n", a, a, a)// a %v is false, %#v is false, %T is boolfmt.Printf("a %%t is %t,  %%T is %T\n", a, a)// a %t is false,  %T is boolb := truefmt.Printf("b %%v is %v, %%#v is %#v, %%T is %T\n", b, b, b)// b %v is true, %#v is true, %T is boolfmt.Printf("b %%t is %t,  %%T is %T\n", b, b)// b %t is true,  %T is bool
}
2.3 整數格式
| 格式化標記 | 格式化含義 | 
|---|---|
| %b | 表示為二進制 | 
| %c | 該值對應的unicode碼值 | 
| %d | 表示為十進制 | 
| %o | 表示為八進制 | 
| %q | 該值對應的單引號括起來的go語法字符字面值,必要時會采用安全的轉義表示 | 
| %x | 表示為十六進制,使用a-f | 
| %X | 表示為十六進制,使用A-F | 
| %U | 表示為Unicode格式:U+1234,等價于"U+%04X" | 
沒有%u。整數如果是無符號類型自然輸出也是無符號的。類似的,也沒有必要指定操作數的尺寸(int8,int64)。
代碼示例:
func main() {var i int = 15fmt.Printf("i %%#v is %#v\n", i) // i %#v is 15fmt.Printf("i %%b is %b\n", i)   // i %b is 1111fmt.Printf("i %%c is %c\n", i)   // i %c is fmt.Printf("i %%d is %d\n", i)   // i %d is 15fmt.Printf("i %%o is %o\n", i)   // i %o is 17fmt.Printf("i %%q is %q\n", i)   // i %q is '\x0f'fmt.Printf("i %%x is %x\n", i)   // i %x is ffmt.Printf("i %%X is %X\n", i)   // i %X is Ffmt.Printf("i %%U is %U\n", i)   // i %U is U+000F
}
2.4 浮點數與復數格式
| 格式化標記 | 格式化含義 | 
|---|---|
| %b | 無小數部分、二進制指數的科學計數法,如-123456p-78;參見strconv.FormatFloat | 
| %e | 科學計數法,如-1234.456e+78 | 
| %E | 科學計數法,如-1234.456E+78 | 
| %f | 有小數部分但無指數部分,如123.456 | 
| %F | 等價于%f | 
| %g | 根據實際情況采用%e或%f格式(以獲得更簡潔、準確的輸出) | 
| %G | 根據實際情況采用%E或%F格式(以獲得更簡潔、準確的輸出) | 
代碼示例:
func main() {var i float32 = 112233445566778899fmt.Printf("i %%#v is %#v,  %%T is %T\n", i, i)//  i %#v is 1.1223345e+17,  %T is float32fmt.Printf("i %%b is %b\n", i) // i %b is 13065693p+33fmt.Printf("i %%e is %e\n", i) // i %e is 1.122334e+17fmt.Printf("i %%E is %E\n", i) // i %E is 1.122334E+17fmt.Printf("i %%f is %f\n", i) // i %f is 112233448269152256.000000fmt.Printf("i %%F is %F\n", i) // i %F is 112233448269152256.000000fmt.Printf("i %%g is %g\n", i) // i %g is 1.1223345e+17fmt.Printf("i %%G is %G\n", i) // i %G is 1.1223345E+17
}
2.5 字符串和[]byte 格式
| 格式化標記 | 格式化含義 | 
|---|---|
| %s | 直接輸出字符串或者[]byte | 
| %q | 該值對應的雙引號括起來的go語法字符串字面值,必要時會采用安全的轉義表示 | 
| %x | 每個字節用兩字符十六進制數表示(使用a-f) | 
| %X | 每個字節用兩字符十六進制數表示(使用A-F) | 
代碼示例:
func main() {a := "hello"b := []byte(a)c := "你好"fmt.Printf("a %%s is %s, %%T is %T\n", a, a) // a %s is hello, %T is stringfmt.Printf("b %%s is %s, %%T is %T\n", b, b) // b %s is hello, %T is []uint8fmt.Printf("c %%s is %s, %%T is %T\n", c, c) // c %s is 你好, %T is stringfmt.Printf("b %%q is %q\n", b)               // b %q is "hello"fmt.Printf("b %%x is %x\n", b)               // b %x is 68656c6c6ffmt.Printf("c %%X is %X\n", c)               // c %X is E4BDA0E5A5BDfmt.Printf("c %%x is %x\n", c)               // c %x is e4bda0e5a5bd
}
2.6 指針格式
| 格式化標記 | 格式化含義 | 
|---|---|
| %p | 表示為十六進制,并加上前導的0x | 
代碼示例:
func main() {a := []int{1, 2, 3, 4}p := &afmt.Printf("*p is %#v\n", *p)  // *p is []int{1, 2, 3, 4}fmt.Printf("p %%p is %p\n", p) // p %p is 0xc00000c060
}
2.7 寬度精度格式
寬度通過一個緊跟在百分號后面的十進制數指定,如果未指定寬度,則表示值時除必需之外不作填充。精度通過(可選的)寬度后跟點號后跟的十進制數指定。
- 如果未指定精度,會使用默認精度;
- 如果點號后沒有跟數字,表示精度為 0。
| 格式化標記 | 格式化含義 | 
|---|---|
| %f | 默認寬度,默認精度 | 
| %9f | 寬度9,默認精度 | 
| %.2f | 默認寬度,精度2 | 
| %9.2f | 寬度9,精度2 | 
| %9.f | 寬度9,精度0 | 
代碼示例:
import "fmt"const PI float32 = 3.14159265358979323846func main() {fmt.Printf("PI %%f is %f\n", PI)fmt.Printf("PI %%f is %9f\n", PI)fmt.Printf("PI %%f is %.3f\n", PI)fmt.Printf("PI %%f is %9.3f\n", PI)fmt.Printf("PI %%f is %9.f\n", PI)
}
輸出結果:
PI %f is 3.141593
PI %f is  3.141593
PI %f is 3.142
PI %f is     3.142
PI %f is         3
寬度和精度格式化控制的是 Unicode 碼值的數量(不同于 C 的 printf ,它的這兩個因數指的是字節的數量)。兩者任一個或兩個都可以使用 * 號取代,此時它們的值將被對應的參數(按’*'號和verb出現的順序,即控制其值的參數會出現在要表示的值前面)控制,這個操作數必須是int類型。
對于大多數類型的值,寬度是輸出字符數目的最小數量,如果必要會用空格填充。對于字符串,精度是輸出字符數目的最大數量,如果必要會截斷字符串。
對于整數,寬度和精度都設置輸出總長度。采用精度時表示右對齊并用 0 填充,而寬度默認表示用空格填充。
對于浮點數,寬度設置輸出總長度;精度設置小數部分長度(如果有的話),除了 %g 和 %G ,此時精度設置總的數字個數。例如,對數字123.45,格式 %6.2f 輸出123.45;格式 %.4g 輸出123.5。 %e 和 %f 的默認精度是6, %g 的默認精度是可以將該值區分出來需要的最小數字個數。
對復數,寬度和精度會分別用于實部和虛部,結果用小括號包裹。因此 %f 用于 1.2+3.4i 輸出(1.200000+3.400000i)。
3. Scanning 格式化
- Scan、- Scanf和- Scanln從標準輸入- os.Stdin讀取文本;
- Fscan、- Fscanf、- Fscanln從指定的- io.Reader接口讀取文本;
- Sscan、- Sscanf、- Sscanln從一個參數字符串讀取文本;
- Scanln、- Fscanln、- Sscanln會在讀取到換行時停止,并要求一次提供一行所有條目;
- Scanf、- Fscanf、- Sscanf只有在格式化文本末端有換行時會讀取到換行為止,其他函數會將換行視為空白。
Scanf 、 Fscanf 、 Sscanf 會根據格式字符串解析參數,類似 Printf 。例如 %x 會讀取一個十六進制的整數, %v 會按對應值的默認格式讀取。格式規則類似 Printf ,有如下區別:
%p 未實現
%T 未實現
%e %E %f %F %g %G 效果相同,用于讀取浮點數或復數類型
%s %v 用在字符串時會讀取空白分隔的一個片段
flag '#'和'+' 未實現
4. 常用函數
4.1 func Printf
func Printf(format string, a ...interface{}) (n int, err error)
Printf 根據 format 參數生成格式化的字符串并寫入標準輸出。參數類型為 interface{} ,這意味著你可以傳遞零個或者多個任意類型參數給它,都能被正確打印。返回寫入的字節數和遇到的任何錯誤。
4.2 func Fprintf
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
Fprintf 根據 format 參數生成格式化的字符串并寫入 w 。返回寫入的字節數和遇到的任何錯誤。
4.3 func Sprintf
func Sprintf(format string, a ...interface{}) string
Sprintf 根據 format 參數生成格式化的字符串并返回該字符串。
4.4 Printf、Fprintf、Sprintf 區別
代碼示例:
func main() {a := "hello"b := "world"fmt.Printf("Printf is %s %s\n", a, b)fmt.Fprintf(os.Stdout, "Fprintf is %s+++++%s\n", a, b)ret := fmt.Sprintf("Sprintf is %s=====%s\n", a, b)fmt.Printf("ret is %s", ret)
}
輸出結果:
Printf is hello world
Fprintf is hello+++++world	// 該打印是 os.Stdout 的輸出,并不是 Fprintf 的輸出
ret is Sprintf is hello=====world
4.5 func Print
func Print(a ...interface{}) (n int, err error)
Print 采用默認格式將其參數格式化并寫入標準輸出。如果兩個相鄰的參數都不是字符串,會在它們的輸出之間添加空格。返回寫入的字節數和遇到的任何錯誤。
4.6 func Fprint
func Fprint(w io.Writer, a ...interface{}) (n int, err error)
Fprint 采用默認格式將其參數格式化并寫入 w 。如果兩個相鄰的參數都不是字符串,會在它們的輸出之間添加空格。返回寫入的字節數和遇到的任何錯誤。
4.7 func Sprint
func Sprint(a ...interface{}) string
Sprint 采用默認格式將其參數格式化,串聯所有輸出生成并返回一個字符串。如果兩個相鄰的參數都不是字符串,會在它們的輸出之間添加空格。
4.8 Print、Fprint、Sprint 區別
代碼示例:
func main() {a := "hello"b := "world"fmt.Print("Print: ", a, b, "\n")fmt.Fprint(os.Stdout, "Fprint: ", a, b, "\n")ret := fmt.Sprint("Sprint: ", a, b, "\n")fmt.Print("ret:", ret)
}
輸出結果:
Print: helloworld
Fprint: helloworld	// 該打印是 os.Stdout 的輸出
ret:Sprint: helloworld
4.9 func Println
func Println(a ...interface{}) (n int, err error)
Println 采用默認格式將其參數格式化并寫入標準輸出。總是會在相鄰參數的輸出之間添加空格并在輸出結束后添加換行符。返回寫入的字節數和遇到的任何錯誤。
4.10 func Fprintln
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)
Fprintln 采用默認格式將其參數格式化并寫入 w ??偸菚谙噜弲档妮敵鲋g添加空格并在輸出結束后添加換行符。返回寫入的字節數和遇到的任何錯誤。
4.11 func Sprintln
func Sprintln(a ...interface{}) string
Sprintln 采用默認格式將其參數格式化,串聯所有輸出生成并返回一個字符串??偸菚谙噜弲档妮敵鲋g添加空格并在輸出結束后添加換行符。
4.12 Println、Fprintln、Sprintln 區別
代碼示例:
func main() {a := "hello"b := "world"fmt.Println("Println: ", a, b)fmt.Fprintln(os.Stdout, "Fprintln: ", a, b)ret := fmt.Sprintln("Sprintln: ", a, b)fmt.Println("ret:", ret)
}
輸出結果:
Println:  hello world
Fprintln:  hello world	// 該打印是 os.Stdout 的輸出
ret: Sprintln:  hello world
4.13 func Errorf
func Errorf(format string, a ...interface{}) error
Errorf 根據 format 參數生成格式化字符串并返回一個包含該字符串的錯誤。
4.14 func Scanf
func Scanf(format string, a ...interface{}) (n int, err error)
Scanf 從標準輸入掃描文本,根據 format 參數指定的格式將成功讀取的空白分隔的值保存進成功傳遞給本函數的參數。返回成功掃描的條目個數和遇到的任何錯誤。
4.15 func Fscanf
func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error)
Fscanf 從 r 掃描文本,根據 format 參數指定的格式將成功讀取的空白分隔的值保存進成功傳遞給本函數的參數。返回成功掃描的條目個數和遇到的任何錯誤。
4.16 func Sscanf
func Sscanf(str string, format string, a ...interface{}) (n int, err error)
Sscanf 從字符串 str 掃描文本,根據 format 參數指定的格式將成功讀取的空白分隔的值保存進成功傳遞給本函數的參數。返回成功掃描的條目個數和遇到的任何錯誤。
4.17 func Scan
func Scan(a ...interface{}) (n int, err error)
Scan 從標準輸入掃描文本,將成功讀取的空白分隔的值保存進成功傳遞給本函數的參數。換行視為空白。返回成功掃描的條目個數和遇到的任何錯誤。如果讀取的條目比提供的參數少,會返回一個錯誤報告原因。
4.18 func Fscan
func Fscan(r io.Reader, a ...interface{}) (n int, err error)
Fscan 從 r 掃描文本,將成功讀取的空白分隔的值保存進成功傳遞給本函數的參數。換行視為空白。返回成功掃描的條目個數和遇到的任何錯誤。如果讀取的條目比提供的參數少,會返回一個錯誤報告原因。
4.19 func Sscan
func Sscan(str string, a ...interface{}) (n int, err error)
Sscan 從字符串 str 掃描文本,將成功讀取的空白分隔的值保存進成功傳遞給本函數的參數。換行視為空白。返回成功掃描的條目個數和遇到的任何錯誤。如果讀取的條目比提供的參數少,會返回一個錯誤報告原因。
4.20 func Scanln
func Scanln(a ...interface{}) (n int, err error)
Scanln 類似 Scan ,但會在換行時才停止掃描。最后一個條目后必須有換行或者到達結束位置。
4.21 func Fscanln
func Fscanln(r io.Reader, a ...interface{}) (n int, err error)
Fscanln 類似 Fscan ,但會在換行時才停止掃描。最后一個條目后必須有換行或者到達結束位置。
4.22 func Sscanln
func Sscanln(str string, a ...interface{}) (n int, err error)
Sscanln 類似 Sscan ,但會在換行時才停止掃描。最后一個條目后必須有換行或者到達結束位置。
參考:
 https://studygolang.com/static/pkgdoc/pkg/fmt.htm
總結
以上是生活随笔為你收集整理的Go 学习笔记(46)— Go 标准库之 fmt(输入/输出格式化参数、Printf/Fprintf/Sprintf区别、Println/Fprintln/Sprintln 区别)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 望穿秋水下一句是什么啊?
- 下一篇: 请问这种类型的电影蓝光原盘用什么下载工具
