Go語言fmt包(輸入,輸出,格式化佔位符)
fmt
是Go語言中的標準庫主要是用來 Go語言中終端輸入輸出以及格式化輸出常用的函數.
fmt
Go 語言標準庫中的 fmt 包提供了打印函數將數據以字符串形式輸出到控制檯、文件、其他滿足 io.Writer 接口的至以及其他字符串中
輸出
標準庫fmt
提供了以下幾種輸出相關的函數.
Print
系列函數會將內容輸出到系統的標準輸出,區別在於Print
函數直接輸入內容到終端,
package main
import "fmt"
func main() {
fmt.Print("hello")
fmt.Print("我叫春生")
fmt.Print("我是北京吳彥祖")
}
結果:
可以看到輸出的結果 都保持在一行,沒有經過任何修飾直接輸出在終端.
Printf
Printf
函數支持格式化輸出字符串.
package main
import "fmt"
func main() {
fmt.Printf("我是春生,人稱北京: %s \n","吳彥祖")
fmt.Printf("是不是季度我的容顏。\n")
}
可以看到我輸出的內容是經過格式化過後的內容,手動添加 \n
和 佔位符
替換.
Println
Println
函數 自定幫我們添加換行符 ,輸出內容獨佔一行.他不支持格式化出去
package main
import "fmt"
func main() {
fmt.Println( "我是春生")
fmt.Println( "人稱北京吳彥祖")
fmt.Println("不能嫉妒我容顏")
}
可以看到 沒個輸出都是獨佔一行的,自動幫我們添加了 \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.Scan
、fmt.Scanf
、fmt.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.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)
Fscan 系列都是和 io 阻塞的有關係 .
Sscan系列
這幾個函數功能分別類似於fmt.Scan
、fmt.Scanf
、fmt.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)
}