Go語言fmt包(輸入,輸出,格式化佔位符)

Go語言fmt包(輸入,輸出,格式化佔位符)

fmt 是Go語言中的標準庫主要是用來 Go語言中終端輸入輸出以及格式化輸出常用的函數.

fmt

Go 語言標準庫中的 fmt 包提供了打印函數將數據以字符串形式輸出到控制檯、文件、其他滿足 io.Writer 接口的至以及其他字符串中

輸出

標準庫fmt提供了以下幾種輸出相關的函數.

Print

Print 系列函數會將內容輸出到系統的標準輸出,區別在於Print 函數直接輸入內容到終端,

package main

import "fmt"

func main() {
	fmt.Print("hello")
	fmt.Print("我叫春生")
	fmt.Print("我是北京吳彥祖")
}

結果:

image-20210125094631914

可以看到輸出的結果 都保持在一行,沒有經過任何修飾直接輸出在終端.

Printf

Printf函數支持格式化輸出字符串.

package main

import "fmt"

func main() {
	fmt.Printf("我是春生,人稱北京: %s \n","吳彥祖")
	fmt.Printf("是不是季度我的容顏。\n")
}
image-20210125094937575

可以看到我輸出的內容是經過格式化過後的內容,手動添加 \n 佔位符替換.

Println

Println 函數 自定幫我們添加換行符 ,輸出內容獨佔一行.他不支持格式化出去

package main

import "fmt"

func main() {
	fmt.Println( "我是春生")
	fmt.Println( "人稱北京吳彥祖")
	fmt.Println("不能嫉妒我容顏")
}
image-20210125095615915

可以看到 沒個輸出都是獨佔一行的,自動幫我們添加了 \n

Fptiny

Fprint系列函數會將內容輸出到一個io.Writer接口類中,我們通常用這個函數往文件中寫入內容.

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) // 自動帶 換行符

例子:

package main

import (
	"fmt"
	"os"
)

func main() {

	// 向標準輸出寫入內容
	// os.Stdout 使用 os.Stdout 只能輸出到 控制檯
	fmt.Fprintln(os.Stdout, "向標準輸出寫入內容") // io結束後輸出內容 
	// os.OpenFile(文件路徑,文件打開模式,文件權限)
	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系列函數會把傳入的數據生成並返回一個字符串

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

例子:

package main

import "fmt"

func main() {
   s1 := fmt.Sprintf("我是春生 人稱: %s","北京吳彥祖")
   s2 := fmt.Sprintln("好好學習 天天向上")
   s3 := fmt.Sprint("勞動人民最光榮")


   fmt.Println(s1)  // 打印結果
   fmt.Println(s2)  // 打印結果
   fmt.Println(s3)  // 打印結果

}

結果:

我是春生 人稱: 北京吳彥祖
好好學習 天天向上

勞動人民最光榮

Process finished with exit code 0

結果可以看到。Sprintf 格式化 轉換結果 賦值給了 s1 最終通過 fmt.Println 打印.

Errorf

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

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

通常使用這種方式來自定義錯誤類型,例如:

package main

import "fmt"

func main() {
	
	err := fmt.Errorf("這是一個錯誤信息:%s","北京吳彥祖報表了")
	fmt.Println(err)
}

Go1.13版本爲fmt.Errorf函數新加了一個%w佔位符用來生成一個可以包裹Error的Wrapping Error。

package main

import (
	"errors"
	"fmt"
)
func main() {
	e := errors.New("原始錯誤e")
	w := fmt.Errorf("Wrap了一個錯誤%w", e)
	fmt.Println(w)
}

格式化佔位符

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

通用佔位符

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

代碼:

package main
import "fmt"
func main() {
	var pi float64 = 3.1415926
	fmt.Printf("%v \n",pi) // %v 會自動推導出當前的變量 是什麼格式 類型輸出
	var o = struct {
		name string
	}{"春生"}
	fmt.Printf("%v \n",o)   //  輸出值
	fmt.Printf("%+v \n",o)  // 結構體輸出 建 和 值
	fmt.Printf("%#v \n",o)  // 以Go的語法輸出
	fmt.Printf("%T \n",o)  //  %T 打印值的類型
	fmt.Printf("%T \n",pi)  // %T 打印值的類型
	fmt.Printf("%% %v",100) // 如果打印的是 帶有 %的特殊 形式 需要加上 %%去注視特殊字符

}

結果:

3.1415926 
{春生} 
{name:春生} 
struct { name string }{name:"春生"} 
struct { name string } 
float64 
% 100
Process finished with exit code 0

布爾型

佔位符 說明
%t true或false
fmt.Printf("%t \n",true)
fmt.Printf("%t \n",false)

結果:

true 
false 

Process finished with exit code 0

整型

佔位符 說明
%b 表示爲二進制
%c 該值對應的unicode碼值
%d 表示爲十進制
%o 表示爲八進制
%x 表示爲十六進制,使用a-f
%X 表示爲十六進制,使用A-F
%U 表示爲Unicode格式:U+1234,等價於”U+%04X”
%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

浮點數與複數

%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)

輸出結果如下:

春生 
"春生" 
e698a5e7949f 
E698A5E7949F 

指針

佔位符 說明
%p 表示爲十六進制,並加上前導的0x
s := "春生"
fmt.Printf("%p\n",&s)

結果:

0xc000010200

Process finished with exit code 0

寬度標識符

寬度通過一個緊跟在百分號後面的十進制數指定,如果未指定寬度,則表示值除了必須之外不作填充. 精度通過(可選的)寬度後跟點號後跟的十進制數指定.

如果爲指定精度,會使用默認精度;如果點號後沒有跟數字嗎,就表示精度爲0

例子:

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

代碼:

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 

Process finished with exit code 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放在正負號後面;

舉個例子:

舉個例子:

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三個函數,可以在程序運行過程中從標準輸入獲取用戶的輸入.

fat.Scan

函數定簽名如下:

func Scan(a ...interface{}) (n int, err error)
  • Scan從標準輸入掃描文本,讀取由空白符分割的值保存到傳遞給本函數的參數中,換行符視爲空白符.
  • 本函數返回成功掃描的數據個數和遇到的任何錯誤.如果讀取的數據個數比提供的參數少,會返回一個錯誤報告原因

代碼:

package main

import "fmt"

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

結果:

春生 
18
false
掃描結果 name:春生 age:18 marridL:false
Process finished with exit code 0

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

fmt.Scanf

函數簽名:

func Scanf(format string, a ...interface{}) (n int, err error)
  • Scanf從標準輸入掃描文本,根據format參數指定的格式去讀取由空白符分隔的值保存到傳遞本函數的參數中
  • 本函數返回成功掃描的數據個數和遇到的任何錯誤.

代碼:

package main

import "fmt"

func main() {
	var (
		name    string
		age     int
		married bool

	)

	fmt.Scanf("1:%v 2:%v 3:%v", &name, &age, &married)
	fmt.Printf("掃描結果 name:%s age:%d married:%t \n", name, age, married)
}

結果:

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

Process finished with exit code 0

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

fmt.Scanln

函數簽名如下:

func Scanln(a ...interface{}) (n int, err error)
  • Scanln類似Scan,它在遇到換行時才停止掃描。最後一個數據後面必須有換行或者到達結束位置。
  • 本函數返回成功掃描的數據個數和遇到的任何錯誤。

代碼:

package main

import "fmt"

func main() {
	var (
		name    string
		age     int
		married bool

	)
	fmt.Scanln(&name,&age,&married)
	fmt.Printf("掃描結果 name:%v age:%v married:%v",name,age,married)
}

結果:

chunsheng 177 true
掃描結果 name:chunsheng age:177 married:true
Process finished with exit code 0

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

bufio.NewReader

有時候我們想完整獲取輸入內容,而輸入的內容可能包含空格、這種情況下可以使用bufio包來實現.

代碼:

package main

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

func main() {
	reader := bufio.NewReader(os.Stdin)  // 標準輸出生成對象
	fmt.Print("請輸入內容:")

	text,_ := reader.ReadString('\n')  // 讀取回車換行

	text = strings.TrimSpace(text)  // strings 方法 去空格 去換行符

	fmt.Printf("%v \n",text)  //打印輸出
	
}

結果:

![image-20210126100955083](/Users/chunsheng/Library/Application Support/typora-user-images/image-20210126100955083.png)

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)

Fscan 系列都是和 io 阻塞的有關係 .

Sscan系列

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

package main

import (
	"fmt"
)

func main() {
	//reader := bufio.NewReader(os.Stdin)  // 標準輸出生成對象
	//fmt.Print("請輸入內容:")
	//text,_ := reader.ReadString('\n')  // 讀取回車換行
	//text = strings.TrimSpace(text)  // strings 方法 去空格 去換行符
	//fmt.Printf("%v \n",text)  //打印輸出

	var (
		name string
		age int
		is bool
	)

	fmt.Scan(&name,&age,&is)     // 讀取由空白符分隔的值保存到傳遞給本函數的參數中 ,換行符視爲空白符
	fmt.Scanln(&name,&age,&is)   //  遇到換行符是才停止掃描。最後一個數據必須有換行符
	fmt.Println(name,age,is) 

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章