fmt

fmt包實現了相似C語言printf和scanf的格式化I/O。主要分爲向外輸出內容和獲取輸入內容兩大部分。安全

向外輸出

標準庫fmt提供瞭如下幾種輸出相關函數。bash

Print

Print系列函數會將內容輸出到系統的標準輸出,區別在於Print函數直接輸出內容,Printf函數支持格式化輸出字符串,Println函數會在輸出內容的結尾添加一個換行符。函數

func Print(a ...interface{}) (n int, err error)
func Printf(format string, a ...interface{}) (n int, err error)
func Println(a ...interface{}) (n int, err error)

  

 

舉個簡單的例子:
func main() { fmt.Print("在終端打印該信息。") name := "沙河小王子" fmt.Printf("我是:%s\n", name) fmt.Println("在終端打印單獨一行顯示") } 執行上面的代碼輸出: 在終端打印該信息。我是:沙河小王子 在終端打印單獨一行顯示

  

Fprint

Fprint系列函數會將內容輸出到一個io.Writer接口類型的變量w中,咱們一般用這個函數往文件中寫入內容。post

func Fprint(w io.Writer, a ...interface{}) (n int, err error)
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error)
func Fprintln(w io.Writer, a ...interface{}) (n int, err error)

  

舉個例子:

// 向標準輸出寫入內容
fmt.Fprintln(os.Stdout, "向標準輸出寫入內容")
fileObj, err := os.OpenFile("./xx.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
	fmt.Println("打開文件出錯,err:", err)
	return
}
name := "沙河小王子"
// 向打開的文件句柄中寫入內容
fmt.Fprintf(fileObj, "往文件中寫如信息:%s", name)
注意,只要知足io.Writer接口的類型都支持寫入。

  

Sprint

Sprint系列函數會把傳入的數據生成並返回一個字符串。spa

func Sprint(a ...interface{}) string
func Sprintf(format string, a ...interface{}) string
func Sprintln(a ...interface{}) string

 

簡單的示例代碼以下:
s1 := fmt.Sprint("沙河小王子") name := "沙河小王子" age := 18 s2 := fmt.Sprintf("name:%s,age:%d", name, age) s3 := fmt.Sprintln("沙河小王子") fmt.Println(s1, s2, s3)
 
      

Errorf

Errorf函數根據format參數生成格式化字符串並返回一個包含該字符串的錯誤。指針

func Errorf(format string, a ...interface{}) error

  

一般使用這種方式來自定義錯誤類型,例如:code

err := fmt.Errorf("這是一個錯誤")

  

格式化佔位符

*printf系列函數都支持format格式化參數,在這裏咱們按照佔位符將被替換的變量類型劃分,方便查詢和記憶。orm

通用佔位符

佔位符 說明
%v 值的默認格式表示
%+v 相似%v,但輸出結構體時會添加字段名
%#v 值的Go語法表示
%T 打印值的類型
%% 百分號
 
示例代碼以下:

fmt.Printf("%v\n", 100)
fmt.Printf("%v\n", false)
o := struct{ name string }{"小王子"}
fmt.Printf("%v\n", o)
fmt.Printf("%#v\n", o)
fmt.Printf("%T\n", o)
fmt.Printf("100%%\n")
輸出結果以下:

100
false
{小王子}
struct { name string }{name:"小王子"}
struct { name string }
100%

  

布爾型

佔位符 說明
%t true或false

整型

佔位符 說明
%b 表示爲二進制
%c 該值對應的unicode碼值
%d 表示爲無符號十進制
%o 表示爲無符號八進制
%#o 表示爲有符號八進制
%x 表示爲十六進制,使用a-f
%#x 表示爲有符號的十六進制
%X 表示爲十六進制,使用A-F
%U 表示爲Unicode格式:U+1234,等價於」U+%04X」
%#u 表示帶打印字符的Unicode
%q 該值對應的單引號括起來的go語法字符字面值,必要時會採用安全的轉義表示
 
示例代碼以下:

n := 65
fmt.Printf("%b\n", n)
fmt.Printf("%c\n", n)
fmt.Printf("%d\n", n)
fmt.Printf("%o\n", n)
fmt.Printf("%x\n", n)
fmt.Printf("%X\n", n)
輸出結果以下:

1000001
A
65
101
41
41

  

浮點數與複數

佔位符 說明
%b 無小數部分、二進制指數的科學計數法,如-123456p-78
%e 科學計數法,如-1234.456e+78
%E 科學計數法,如-1234.456E+78
%f 有小數部分但無指數部分,如123.456
%F 等價於%f
%g 根據實際狀況採用%e或%f格式(以得到更簡潔、準確的輸出)
%G 根據實際狀況採用%E或%F格式(以得到更簡潔、準確的輸出)
示例代碼以下:

f := 12.34
fmt.Printf("%b\n", f)
fmt.Printf("%e\n", f)
fmt.Printf("%E\n", f)
fmt.Printf("%f\n", f)
fmt.Printf("%g\n", f)
fmt.Printf("%G\n", f)
輸出結果以下:

6946802425218990p-49
1.234000e+01
1.234000E+01
12.340000
12.34
12.34

  

字符串和[]byte對象

佔位符 說明
%s 直接輸出字符串或者[]byte
%q 該值對應的雙引號括起來的go語法字符串字面值,必要時會採用安全的轉義表示
%x 每一個字節用兩字符十六進制數表示(使用a-f
%X 每一個字節用兩字符十六進制數表示(使用A-F)
 
示例代碼以下:

s := "小王子"
fmt.Printf("%s\n", s)
fmt.Printf("%q\n", s)
fmt.Printf("%x\n", s)
fmt.Printf("%X\n", s)
輸出結果以下:

小王子
"小王子"
e5b08fe78e8be5ad90
E5B08FE78E8BE5AD90

  

指針

佔位符 說明
%p 表示爲十六進制,並加上前導的0x
%#p 表示爲十六進制,不加上前導0x
 
示例代碼以下:

a := 10
fmt.Printf("%p\n", &a)
fmt.Printf("%#p\n", &a)
輸出結果以下:

0xc000094000
c000094000

  

寬度標識符

寬度經過一個緊跟在百分號後面的十進制數指定,若是未指定寬度,則表示值時除必需以外不做填充。精度經過(可選的)寬度後跟點號後跟的十進制數指定。若是未指定精度,會使用默認精度;若是點號後沒有跟數字,表示精度爲0。舉例以下:blog

佔位符 說明
%f 默認寬度,默認精度
%9f 寬度9,默認精度
%.2f 默認寬度,精度2
%9.2f 寬度9,精度2
%9.f 寬度9,精度0
%.2g 最多出現2個數
 
示例代碼以下:

n := 12.34
fmt.Printf("%f\n", n)
fmt.Printf("%9f\n", n)
fmt.Printf("%.2f\n", n)
fmt.Printf("%9.2f\n", n)
fmt.Printf("%9.f\n", n)
輸出結果以下:

12.340000
12.340000
12.34
    12.34
       12

  

其餘falg

佔位符 說明
’+’ 老是輸出數值的正負號;對%q(%+q)會生成所有是ASCII字符的輸出(經過轉義);
’ ‘ 對數值,正數前加空格而負數前加負號;對字符串採用%x或%X時(% x或% X)會給各打印的字節之間加空格
’-’ 在輸出右邊填充空白而不是默認的左邊(即從默認的右對齊切換爲左對齊);
’#’ 八進制數前加0(%#o),十六進制數前加0x(%#x)或0X(%#X),指針去掉前面的0x(%#p)對%q(%#q),對%U(%#U)會輸出空格和單引號括起來的go字面值;
‘0’ 使用0而不是空格填充,對於數值類型會把填充的0放在正負號後面;
 
舉個例子:

s := "小王子"
fmt.Printf("%s\n", s)
fmt.Printf("%5s\n", s)
fmt.Printf("%-5s\n", s)
fmt.Printf("%5.7s\n", s)
fmt.Printf("%-5.7s\n", s)
fmt.Printf("%5.2s\n", s)
fmt.Printf("%05s\n", s)
輸出結果以下:

小王子
  小王子
小王子  
  小王子
小王子  
   小王
00小王子

  

獲取輸入

Go語言fmt包下有fmt.Scanfmt.Scanffmt.Scanln三個函數,能夠在程序運行過程當中從標準輸入獲取用戶的輸入。

fmt.Scan

函數定簽名以下:

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

  

  • Scan從標準輸入掃描文本,讀取由空白符分隔的值保存到傳遞給本函數的參數中,換行符視爲空白符。
  • 本函數返回成功掃描的數據個數和遇到的任何錯誤。若是讀取的數據個數比提供的參數少,會返回一個錯誤報告緣由。

具體代碼示例以下:

func main() {
	var (
		name    string
		age     int
		married bool
	)
	fmt.Scan(&name, &age, &married)
	fmt.Printf("掃描結果 name:%s age:%d married:%t \n", name, age, married)
}

  

將上面的代碼編譯後在終端執行,在終端依次輸入小王子28false使用空格分隔。

$ ./scan_demo 
小王子 28 false
掃描結果 name:小王子 age:28 married:false

fmt.Scan從標準輸入中掃描用戶輸入的數據,將以空白符分隔的數據分別存入指定的參數。

fmt.Scanf

函數簽名以下:

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

  

  • Scanf從標準輸入掃描文本,根據format參數指定的格式去讀取由空白符分隔的值保存到傳遞給本函數的參數中。
  • 本函數返回成功掃描的數據個數和遇到的任何錯誤。

代碼示例以下:

func main() {
	var (
		name    string
		age     int
		married bool
	)
	fmt.Scanf("1:%s 2:%d 3:%t", &name, &age, &married)
	fmt.Printf("掃描結果 name:%s age:%d married:%t \n", name, age, married)
}

  

將上面的代碼編譯後在終端執行,在終端按照指定的格式依次輸入小王子28false

$ ./scan_demo 
1:小王子 2:28 3:false
掃描結果 name:小王子 age:28 married:false

fmt.Scanf不一樣於fmt.Scan簡單的以空格做爲輸入數據的分隔符,fmt.Scanf爲輸入數據指定了具體的輸入內容格式,只有按照格式輸入數據纔會被掃描並存入對應變量。

例如,咱們仍是按照上個示例中以空格分隔的方式輸入,fmt.Scanf就不能正確掃描到輸入的數據。

$ ./scan_demo 
小王子 28 false
掃描結果 name: age:0 married:false

fmt.Scanln

函數簽名以下:

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

  

  • Scanln相似Scan,它在遇到換行時才中止掃描。最後一個數據後面必須有換行或者到達結束位置。
  • 本函數返回成功掃描的數據個數和遇到的任何錯誤。

具體代碼示例以下:

func main() {
	var (
		name    string
		age     int
		married bool
	)
	fmt.Scanln(&name, &age, &married)
	fmt.Printf("掃描結果 name:%s age:%d married:%t \n", name, age, married)
}

  

將上面的代碼編譯後在終端執行,在終端依次輸入小王子28false使用空格分隔。

$ ./scan_demo 
小王子 28 false
掃描結果 name:小王子 age:28 married:false

fmt.Scanln遇到回車就結束掃描了,這個比較經常使用。

bufio.NewReader

有時候咱們想完整獲取輸入的內容,而輸入的內容可能包含空格,這種狀況下可使用bufio包來實現。示例代碼以下:

func bufioDemo() {
	reader := bufio.NewReader(os.Stdin) // 從標準輸入生成讀對象
	fmt.Print("請輸入內容:")
	text, _ := reader.ReadString('\n') // 讀到換行
	text = strings.TrimSpace(text)
	fmt.Printf("%#v\n", text)
}

  

Fscan系列

這幾個函數功能分別相似於fmt.Scanfmt.Scanffmt.Scanln三個函數,只不過它們不是從標準輸入中讀取數據而是從io.Reader中讀取數據。

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)

  

Sscan系列

這幾個函數功能分別相似於fmt.Scanfmt.Scanffmt.Scanln三個函數,只不過它們不是從標準輸入中讀取數據而是從指定字符串中讀取數據。

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)