1. 程式人生 > 其它 >golang fmt包

golang fmt包

fmt

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

向外輸出

標準庫fmt提供了以下幾種輸出相關函式。

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)

Fprint

Fprint系列函式會將內容輸出到一個io.Writer介面型別的變數w中,我們通常用這個函式往檔案中寫入內容。

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)

Sprint

Sprint系列函式會把傳入的資料生成並返回一個字串。

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

Errorf

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

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

格式化佔位符

*printf系列函式都支援format格式化引數,在這裡我們按照佔位符將被替換的變數型別劃分,方便查詢和記憶。

通用佔位符

佔位符 說明
%v 值的預設格式表示
%+v 類似%v,但輸出結構體時會新增欄位名
%#v 值的Go語法表示
%T 列印值的型別
%% 百分號

布林型

佔位符 說明
%t true或false

整型

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

浮點數與複數

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

字串和[]byte

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

指標

佔位符 說明
%p 表示為十六進位制,並加上前導的0x

寬度識別符號

寬度通過一個緊跟在百分號後面的十進位制數指定,如果未指定寬度,則表示值時除必需之外不作填充。精度通過(可選的)寬度後跟點號後跟的十進位制數指定。如果未指定精度,會使用預設精度;如果點號後沒有跟數字,表示精度為0。舉例如下:

佔位符 說明
%f 預設寬度,預設精度
%9f 寬度9,預設精度
%.2f 預設寬度,精度2
%9.2f 寬度9,精度2
%9.f 寬度9,精度0

其他falg

佔位符 說明
’+’ 總是輸出數值的正負號;對%q(%+q)會生成全部是ASCII字元的輸出(通過轉義);
’ ‘ 對數值,正數前加空格而負數前加負號;對字串採用%x或%X時(% x或% X)會給各列印的位元組之間加空格
’-’ 在輸出右邊填充空白而不是預設的左邊(即從預設的右對齊切換為左對齊);
’#’ 八進位制數前加0(%#o),十六進位制數前加0x(%#x)或0X(%#X),指標去掉前面的0x(%#p)對%q(%#q),對%U(%#U)會輸出空格和單引號括起來的go字面值;
‘0’ 使用0而不是空格填充,對於數值型別會把填充的0放在正負號後面;

獲取輸入

Go語言fmt包下有fmt.Scan、fmt.Scanf、fmt.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)
}

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

$ ./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)
}

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

$ ./scan_demo 
1:zhy 2:18 3:false
掃描結果 name:zhy age:18 married:false

fmt.Scanf不同於fmt.Scan簡單的以空格作為輸入資料的分隔符,fmt.Scanf為輸入資料指定了具體的輸入內容格式,只有按照格式輸入資料才會被掃描並存入對應變數。

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

$ ./scan_demo 
zhy 18 false
掃描結果 zhy: 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)
}

$ ./scan_demo 
zhy 18 false
掃描結果 name:zhy 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.Scan、fmt.Scanf、fmt.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.Scan、fmt.Scanf、fmt.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)

參考文章:https://www.liwenzhou.com/posts/Go/go_fmt/