fmt 是 Go 語言中的一個常用標準庫,它用於格式化輸入和輸出資料。fmt 包提供了一系列函數,可以幫助你將資料以特定的格式列印到標準輸出(通常是終端)或將資料格式化為字串以供後續處理。這個庫的名稱 "fmt" 來自於 "format",因為它主要用於格式化資料。
fmt 包的主要功能包括:
Print
, Printf
, Println
, Fprint
, Fprintf
, 和 Fprintln
用於將資料輸出到標準輸出或指定的 io.Writer。你可以使用這些函數將資料以不同的格式列印到螢幕上或檔案中。Scan
, Scanf
, 和 Scanln
函數實現的。這對於從使用者獲取輸入資料非常有用。Sprintf
函數將資料格式化為字串而不是直接輸出到標準輸出,這對於構建紀錄檔訊息或其他需要格式化的字串很有用。Errorf
函數,用於將格式化的錯誤訊息作為 error 型別返回,方便錯誤處理。%d
(整數),%f
(浮點數),%s
(字串)等。標準庫 fmt
提供了多種用於輸出的函數,每個函數都有不同的用途和輸出方式。以下是一些常用的輸出相關函數:
Print
:用於將文字輸出到標準輸出。它接受任意數量的引數,並將它們串聯成一個字串輸出,不會新增換行符。Printf
:用於格式化輸出到標準輸出。它接受一個格式化字串和一系列引數,根據格式化字串的預留位置將引數格式化並輸出。Println
:類似於 Print
,但會在輸出後自動新增一個換行符。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("Hello, ", "world")
name := "Alice"
age := 30
fmt.Printf("Hello, %s. You are %d years old.\n", name, age)
fmt.Println("Hello, world")
}
Fprint
系列函數用於將文字輸出到指定的 io.Writer
介面,而不僅僅是標準輸出。你可以將文字輸出到檔案、網路連線等。這些函數的參數列包括一個 io.Writer
引數,以及任意數量的引數。
Fprint
:將文字輸出到指定的 io.Writer
。Fprintf
:將格式化文字輸出到指定的 io.Writer
。Fprintln
:將帶有換行符的文字輸出到指定的 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)
舉個例子:
func main() {
// 向標準輸出寫入內容
fmt.Fprintln(os.Stdout, "向標準輸出寫入內容")
fileObj, err := os.OpenFile("./output.txt", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
fmt.Println("開啟檔案出錯,err:", err)
return
}
name := "jarvis"
// 向開啟的檔案控制程式碼中寫入內容
fmt.Fprintf(fileObj, "往檔案中寫如資訊:%s", name)
}
這個範例建立了一個名為 "output.txt" 的檔案,並將資料寫入檔案中。
Sprint
系列函數用於將文字輸出到字串中,而不是標準輸出或檔案。它們將文字格式化為字串並返回結果。
Sprint
:將文字輸出到字串。Sprintf
:將格式化文字輸出到字串。Sprintln
:將帶有換行符的文字輸出到字串。func Sprint(a ...interface{}) string
func Sprintf(format string, a ...interface{}) string
func Sprintln(a ...interface{}) string
簡單的範例程式碼如下:
func main() {
s1 := fmt.Sprint("jarvis")
name := "jarvis"
age := 18
s2 := fmt.Sprintf("name:%s,age:%d", name, age)
s3 := fmt.Sprintln("jarvis")
fmt.Println(s1, s2, s3)
}
Errorf
系列函數用於建立格式化的錯誤訊息並返回一個 error
型別的值。這允許你將格式化的錯誤訊息返回給呼叫者,以便更好地進行錯誤處理。這些函數的用法類似於 Sprintf
,但它們返回一個 error
值而不是字串。
Errorf
:根據format
引數生成格式化字串並返回一個包含該字串的錯誤。func Errorf(format string, a ...interface{}) error
通常使用這種方式來自定義錯誤型別,例如:
err := fmt.Errorf("這是一個錯誤")
*printf
系列函數都支援format格式化引數,在這裡我們按照預留位置將被替換的變數型別劃分,方便查詢和記憶。
通用預留位置用於格式化不同型別的資料:
預留位置 | 說明 |
---|---|
%v | 值的預設格式表示 |
%+v | 類似%v,但輸出結構體時會新增欄位名 |
%#v | 值的Go語法表示 |
%T | 列印值的型別 |
%% | 百分號 |
程式碼範例:
func main() {
fmt.Printf("%v\n", 100)
fmt.Printf("%v\n", false)
o := struct{ name string }{"jarvis"}
fmt.Printf("%v\n", o)
fmt.Printf("%#v\n", o)
fmt.Printf("%T\n", o)
fmt.Printf("100%%\n")
}
預留位置 | 說明 |
---|---|
%t | true或false |
預留位置 | 說明 |
---|---|
%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)
預留位置 | 說明 |
---|---|
%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)
預留位置 | 說明 |
---|---|
%s | 直接輸出字串或者[]byte |
%q | 該值對應的雙引號括起來的go語法字串字面值,必要時會採用安全的跳脫表示 |
%x | 每個位元組用兩字元十六進位制數表示(使用a-f |
%X | 每個位元組用兩字元十六進位制數表示(使用A-F) |
範例程式碼如下:
s := "jarvis"
fmt.Printf("%s\n", s)
fmt.Printf("%q\n", s)
fmt.Printf("%x\n", s)
fmt.Printf("%X\n", s)
預留位置 | 說明 |
---|---|
%p | 表示為十六進位制,並加上前導的0x |
範例程式碼如下:
a := 18
fmt.Printf("%p\n", &a)
fmt.Printf("%#p\n", &a)
寬度通過一個緊跟在百分號後面的十進位制數指定,如果未指定寬度,則表示值時除必需之外不作填充。精度通過(可選的)寬度後跟點號後跟的十進位制數指定。如果未指定精度,會使用預設精度;如果點號後沒有跟數位,表示精度為0。舉例如下
預留位置 | 說明 |
---|---|
%f | 預設寬度,預設精度 |
%9f | 寬度9,預設精度 |
%.2f | 預設寬度,精度2 |
%9.2f | 寬度9,精度2 |
%9.f | 寬度9,精度0 |
範例程式碼如下:
n := 88.88
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)
預留位置 | 說明 |
---|---|
‘+’ | 總是輸出數值的正負號;對%q(%+q)會生成全部是ASCII字元的輸出(通過跳脫); |
’ ' | 對數值,正數前加空格而負數前加負號;對字串採用%x或%X時(% x或% X)會給各列印的位元組之間加空格 |
‘-’ | 在輸出右邊填充空白而不是預設的左邊(即從預設的右對齊切換為左對齊); |
‘#’ | 八進位制數前加0(%#o),十六進位制數前加0x(%#x)或0X(%#X),指標去掉前面的0x(%#p)對%q(%#q),對%U(%#U)會輸出空格和單引號括起來的go字面值; |
‘0’ | 使用0而不是空格填充,對於數值型別會把填充的0放在正負號後面; |
舉個例子:
s := "jarvis"
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)
Go 語言的 fmt
包提供了 fmt.Scan
、fmt.Scanf
和 fmt.Scanln
這三個函數,用於從標準輸入獲取使用者的輸入。這些函數允許你與使用者互動,從標準輸入流中讀取不同型別的資料並將其儲存在相應的變數中。
Scan
函數用於從標準輸入中獲取使用者的輸入,並將輸入的資料儲存在變數中。它根據空格分隔輸入,適合獲取多個輸入值。
函數定義如下:
func Scan(a ...interface{}) (n int, err error)
具體程式碼範例如下:
package main
import "fmt"
func main() {
var name string
var age int
fmt.Print("Enter your name: ")
fmt.Scan(&name)
fmt.Print("Enter your age: ")
fmt.Scan(&age)
fmt.Printf("Name: %s, Age: %d\n", name, age)
}
在這個範例中,fmt.Scanf
使用格式字串 %s %d
來解析輸入的姓名和年齡。
Scanln
函數用於從標準輸入中獲取使用者的輸入,並將輸入的資料儲存在變數中,每行一個變數。它通常用於獲取多個輸入值,每個值在單獨的行中輸入。
函數定義如下:
func Scanln(a ...interface{}) (n int, err error)
程式碼範例:
package main
import "fmt"
func main() {
var name string
var age int
fmt.Print("Enter your name: ")
fmt.Scanln(&name)
fmt.Print("Enter your age: ")
fmt.Scanln(&age)
fmt.Printf("Name: %s, Age: %d\n", name, age)
}
在上面的範例中,fmt.Scanln
用於獲取使用者輸入的姓名和年齡,並將它們儲存在相應的變數中。輸入的每一行都對應一個變數。
Scanf
函數用於根據格式規範解析輸入,並將資料儲存在變數中。它允許你指定輸入的格式,並可以處理不同型別的資料。
函數簽名如下:
func Scanf(format string, a ...interface{}) (n int, err error)
程式碼範例如下:
package main
import "fmt"
func main() {
var name string
var age int
fmt.Print("Enter your name and age: ")
fmt.Scanf("%s %d", &name, &age)
fmt.Printf("Name: %s, Age: %d\n", name, age)
}
在這個範例中,fmt.Scanf
使用格式字串 %s %d
來解析輸入的姓名和年齡。
bufio
包獲取輸入bufio
包提供了一種更靈活的方式來處理輸入,特別是在需要完整讀取一行或多行輸入的情況下。你可以使用 bufio.NewReader
建立一個輸入緩衝區,然後使用 ReadString
函數來讀取輸入,直到指定的分隔符(例如換行符 \n
)。這允許你獲取包含空格在內的完整輸入內容。
func bufioDemo() {
reader := bufio.NewReader(os.Stdin) // 從標準輸入生成讀物件
fmt.Print("請輸入內容:")
text, _ := reader.ReadString('\n') // 讀取直到換行符
text = strings.TrimSpace(text)
fmt.Printf("%#v\n", text)
}
Fscan
系列函數Fscan
系列函數允許你從 io.Reader
介面中讀取資料,而不僅僅是標準輸入。這些函數與 fmt.Scan
、fmt.Scanf
和 fmt.Scanln
類似,但允許你從任何實現 io.Reader
介面的地方讀取資料。
Fscan
:從 io.Reader
中讀取資料。Fscanln
:從 io.Reader
中讀取一行資料。Fscanf
:根據指定的格式從 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)
程式碼範例:
package main
import (
"fmt"
"strings"
)
func main() {
input := "42 John"
reader := strings.NewReader(input) // 從字串生成讀物件
var age int
var name string
n, err := fmt.Fscanf(reader, "%d %s", &age, &name)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Read %d values: Age: %d, Name: %s\n", n, age, name)
}
Sscan
系列函數Sscan
系列函數允許你從字串中讀取資料,而不僅僅是從標準輸入。這些函數與 fmt.Scan
、fmt.Scanf
和 fmt.Scanln
類似,但允許你從字串中讀取資料。
Sscan
:從字串中讀取資料。Sscanln
:從字串中讀取一行資料。Sscanf
:根據指定的格式從字串中讀取資料。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)
程式碼範例:
package main
import (
"fmt"
)
func main() {
input := "Alice 30"
var name string
var age int
n, err := fmt.Sscanf(input, "%s %d", &name, &age)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Printf("Read %d values: Name: %s, Age: %d\n", n, name, age)
}