golang fmt.printf I/O 函數格式化說明

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

[TOC]

說明

fmt 包實現了格式化 I/O 函數,類似於 C 的 printf 和 scanf
格式“預留位置”衍生自 C,但比 C 更簡單

常用格式化輸出

fmt.Printf("start at number %v, end count %v\n",start, count)

注意參數輸出數量和預留位置數量要一致

IDEA開發快速格式化模板

使用IDEA開發可以配置自訂代碼模板快速產生

Settings -> Editor -> Live Templates

選中 go 語言展開 選則增加一條

  • Abbreviation 填寫 fpf
  • Description 填寫 print fmt format
  • Template text
fmt.Printf("$END$",$VAR$)
  • Applicable in 點擊右側 Define選中 Go: statenebt

Paste_Image.png

使用時在Go語言編輯的函數中輸入 fpf 就會自動開始編寫格式化輸出


Paste_Image.png

同理可以配置

fpfl 自動模板,協助填寫一個格式化後自動換行,內容

fmt.Printf("$END$\n",$VAR$)

喜歡log的輸出也可以自己定義模板

預留位置

一般預留位置

符號 說明
%v 相應值的預設格式
%+v 在列印結構體時,預設格式,會添加欄位名
%#v 相應值的 Go 文法表示
%T 相應值的類型的 Go 文法表示
%% 字面上的百分比符號,並非值的預留位置

布爾預留位置

符號 說明
%t 單詞 true 或 false

整數預留位置

符號 說明
%b 二進位表示
%c 相應 Unicode 碼點所表示的字元
%d 十進位表示
%o 八進位表示
%q 單引號圍繞的字元字面值,由 Go 文法安全地轉義
%x 十六進位表示,字母形式為小寫 a-f
%X 十六進位表示,字母形式為大寫 A-F
%U Unicode 格式:U+1234,等同於 "U+%04X"

浮點數及其複合構成預留位置

符號 說明
%b 無小數部分的,指數為二的冪的科學計數法,與 strconv.FormatFloat 的 'b' 轉換格式一致。例如 -123456p-78
%e 科學計數法,例如 -1234.456e+78
%E 科學計數法,例如 -1234.456E+78
%f 有小數點而無指數,例如 123.456
%g 根據情況選擇 %e 或 %f 以產生更緊湊的(無末尾的 0)輸出
%G 根據情況選擇 %E 或 %f 以產生更緊湊的(無末尾的 0)輸出

字串與位元組切片預留位置

符號 說明
%s 字串或切片的無解譯位元組
%q 雙引號圍繞的字串,由 Go 文法安全地轉義
%x 十六進位,小寫字母,每位元組兩個字元
%X 十六進位,大寫字母,每位元組兩個字元

指標

符號 說明
%p 十六進位表示,首碼 0x
  • 注意

這裡沒有 'u' 標記。若整數為無符號類型,他們就會被列印成無符號的
類似地, 這裡也不需要指定運算元的大小(int8,int64)。
寬度與精度的控制格式以 Unicode 碼點為單位。(這點與 C 的 printf 不同, 它以位元組數為單位。)
二者或其中之一均可用字元 '*' 表示, 此時它們的值會從下一個運算元中擷取,該運算元的類型必須為 int。

// 寬度與精度的控制以 Unicode 碼點為單位fmt.Printf("\"%8s\"\n", "123456") // 最大長度為 8// "  123456"fmt.Printf("\"%8s\"\n", "Hello")   // 最大長度為 8// "      Hello"// 寬度與精度均可用字元 '*' 表示fmt.Printf("%0*.*f \n", 8, 3, 13.25) // 總長度 8,小數位元 3fmt.Printf("%08.3f \n", 13.25)       // 總長度 8,小數位元 3// 0013.250

對數值而言,寬度為該數值佔用地區的最小寬度;精度為小數點之後的位元
但對於 %g/%G 而言,精度為所有數位總數。

例如,對於 123.45,格式 %6.2f 會列印 123.45,而 %.4g 會列印 123.5。
%e 和 %f 的預設精度為 6;但對於 %g 而言,它的預設精度為確定該值所必須的最小位元

  • 對大多數值而言,寬度為輸出的最小字元數,如果必要的話會為已格式化的形式填充空格。
  • 對字串而言,精度為輸出的最大字元數,如果必要的話會直接截斷。
// 寬度與精度標記字串fmt.Printf("%8q", "ABC")         // 最小長度為 8(包括 %q 的引號字元)//    "ABC"fmt.Printf("%.8q", "1234567890") // 最大長度為 8(不包括 %q 的引號字元)// "12345678"

其它標記

符號 說明
+ 總列印數值的加號或減號;對於 %q(%+q)保證只輸出 ASCII 編碼的字元
- 在右側而非左側填充空格(靠左對齊該地區)
# 備用格式:對八進位添加前置 0(%#o),對十六進位添加前置 0x(%#x)或 0X(%#X)對 %p(%#p)去掉前置 0x
  • 如果可能的話,%q(%#q)會列印原始(即反引號圍繞的)字串
  • 如果是可列印字元,%U(%#U)會寫出該字元的 Unicode 編碼形式(如字元 x 會被列印成 U+0078 'x')
  • ' ' (空格)為數值中省略的加號或減號留出空白(% d);以十六進位(% x, % X)列印字串或切片時,在位元組之間用空格隔開
fmt.Printf("% x\n", "Hello")// 48 65 6c 6c 6f

0 填充前置的 0 而非空格;對於數字,這會將填充移到加號或減號之後

  • 注意

標記有時會被預留位置忽略,所以不要指望它們。例如十進位沒有備用格式,因此 %#d 與 %d 的行為相同
對於每一個 Printf 類的函數,都有一個 Print 函數,該函數不接受任何格式化, 它等價於對每一個運算元都應用 %v
另一個變參函數 Println 會在運算元之間插入空白, 並在末尾追加一個分行符號
不考慮預留位置的話,如果運算元是介面值,就會使用其內部的具體值,而非介面本身

因此:

var i interface{} = 23fmt.Printf("%v\n", i)// 會列印 23
  • 若一個運算元實現了 Formatter 介面,該介面就能更好地用於控制格式化。
  • 若其格式(它對於 Println 等函數是隱式的 %v)對於字串是有效(%s %q %v %x %X),以下兩條規則也適用:
  • 若一個運算元實現了 error 介面,Error 方法就能將該對象轉換為字串,隨後會根據預留位置的需要進行格式化。
  • 若一個運算元實現了 String() string 方法,該方法能將該對象轉換為字串,隨後會根據預留位置的需要進行格式化。
// 為避免以下這類遞迴的情況type X stringfunc (x X) String() string { return Sprintf("<%s>", x) }// 需要在遞迴前轉換該值func (x X) String() string { return Sprintf("<%s>", string(x)) }

格式化錯誤輸出

如果給預留位置提供了無效的實參(例如將一個字串提供給 %d),所產生的字串會包含該問題的描述,如下例所示:

// 類型錯誤或預留位置未知:%!verb(type=value)Printf("%d", hi)// %!d(string=hi)// 實參太多:%!(EXTRA type=value)Printf("hi", "guys")// hi%!(EXTRA string=guys)// 實參太少:%!verb(MISSING)Printf("hi%d")// hi %!d(MISSING)// 寬度或精度不是 int 類型:%!(BADWIDTH)或 %!(BADPREC)Printf("%*s", 4.5, "hi")// %!(BADWIDTH)hiPrintf("%.*s", 4.5, "hi")// %!(BADPREC)hi

所有錯誤都始於“%!”,有時緊跟著單個字元(預留位置),並以小括弧括住的描述結尾

掃描

一組類似的函數通過掃描已格式化的文本來產生值

函數 說明
Scan、Scanf 和 Scanln 從 os.Stdin 中讀取
Fscan、Fscanf 和 Fscanln 從指定的 io.Reader 中讀取
Sscan、Sscanf 和 Sscanln 從實參字串中讀取
Scanln、Fscanln 和 Sscanln 在分行符號處停止掃描,且需要條目緊隨分行符號之後
Scanf、Fscanf 和 Sscanf 需要輸入分行符號來匹配格式中的分行符號;其它函數則將分行符號視為空白格
Scanf、Fscanf 和 Sscanf 根據格式字串解析實參,類似於 Printf

例如,%x 會將一個整數掃描為十六進位數,而 %v 則會掃描該值的預設表現格式

格式化行為類似於 Printf,但也有如下例外:

  • %p 沒有實現
  • %T 沒有實現
  • %e %E %f %F %g %G 都完全等價,且可掃描任何浮點數或複合數值
  • %s 和 %v 在掃描字串時會將其中的空格作為分隔字元
  • 標記 # 和 + 沒有實現

  • 在使用 %v 預留位置掃描整數時,可接受友好的進位首碼 0(八進位)和 0x(十六進位)

寬度被解釋為輸入的文本(%5s 意為最多從輸入中讀取 5 個符文來掃描成字串),而掃描函數則沒有精度的文法(沒有 %5.2f,只有 %5f)

當以某種格式進行掃描時,無論在格式中還是在輸入中,所有非空的連續空白字元 (除分行符號外)都等價於單個空格

  • 由於這種限制,格式字串文本必須匹配輸入的文本,如果不匹配,掃描過程就會停止,並返回已掃描的實參數
  • 在所有的掃描參數中,若一個運算元實現了 Scan 方法(即它實現了 Scanner 介面),該運算元將使用該方法掃描其文本

此外,若已掃描的實參數少於所提供的實參數,就會返回一個錯誤

所有需要被掃描的實參都必須是基本類型或實現了 Scanner 介面的類型

  • 注意:

Fscan 等函數會從輸入中多讀取一個字元(符文),因此,如果迴圈調用掃描函數,可能會跳過輸入中的某些資料

一般只有在輸入的資料中沒有空白符時該問題才會出現。

  • 若提供給 Fscan 的讀取器實現了 ReadRune,就會用該方法讀取字元
  • 若此讀取器還實現了 UnreadRune 方法,就會用該方法儲存字元,而連續的調用將不會遺失資料
  • 若要為沒有 ReadRune 和 UnreadRune 方法的讀取器加上這些功能,需使用 bufio.NewReader

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.