1. 程式人生 > 實用技巧 >fmt語法+範例(fmt version :7.0.1)

fmt語法+範例(fmt version :7.0.1)

本文翻譯:https://fmt.dev/latest/syntax.html

fmt版本:7.0.1

本文僅為參考,請以官方文件為準。

水平有限,歡迎指正。有興趣,參閱官方文件

本文僅為參考,請以實際情況為準。

-------------------------------- 正文開始 ---------------------------------

本文將介紹 fmt::format()和fmt::print()之類的格式化函式使用

A、格式化字串有佔位符,用大括號{}表示佔位,格式化字串放在{}中間。沒有放在{}之間的字串被視為字串輸出。 如果需要輸出的字串中有大括號{},可以額外增加一個大括號來實現。例如: {{ 和 }}。

B、佔位符語法如下:

replacement_field ::= "{" [arg_id] [":" format_spec] "}"
arg_id ::= integer | identifier
integer ::= digit+
digit ::= "0"..."9"
identifier ::= id_start id_continue*
id_start ::= "a"..."z" | "A"..."Z" | "_"
id_continue ::= id_start | digit

  

  1、用不非正式的話說,替換欄位可用以 arg_id 開頭,該引數指定要格式化其值並將其插入輸出的引數,而不是替換欄位。可選的arg_id放在format_spec的後面,其後是冒號':'。這些指定替換值的非預設格式。

 

  2、如果格式字串中的數字arg_ids依次為0、1、2,...,則可以全部省略(不只是某些數字),數字0、1、2,...將按此順序自動插入。

  3、命名引數可以通過其名稱或索引來引用。例如:

"First, thou shalt count to {0}" // 替換第一個引數
"Bring me a {}" // 隱式引用第一個引數
"From {} to {}" // 這行程式碼和 "From {0} to {1}"功效相同

  

  4、format_spec 欄位包含有關如何顯示值的規範,包括欄位寬度,對齊方式,填充,小數精度等詳細資訊。每種值型別都可以定義自己的“formatting mini-language”或對format_spec的解釋。

  

  5、大多數內建型別都支援通用的formatting mini-language,這將在下一節中進行介紹。

  

  6、format_spec欄位還可以在其中的某些位置包含巢狀的替換欄位。這些巢狀的替換欄位只能包含一個引數id。格式規格是不允許的。這將允許動態指定值的格式。

C、Mini-Language的格式規範

  1、在格式字串中包含的替換欄位中使用“格式規範”來定義如何顯示單個值。每種格式表型別可以定義如何解釋格式規範。


  2、 儘管某些格式化選項僅受數字型別支援,但大多數內建型別都為格式規範實現了以下選項。

  3、標準格式說明符的一般形式為:

format_spec ::= [[fill]align][sign]["#"]["0"][width]["." precision][type]
fill ::= <a character other than '{' or '}'>
align ::= "<" | ">" | "^"
sign ::= "+" | "-" | " "
width ::= integer | "{" [arg_id] "}"
precision ::= integer | "{" [arg_id] "}"
type ::= int_type | "a" | "A" | "c" | "e" | "E" | "f" | "F" | "g" | "G" | "L" | "p" | "s"
int_type ::= "b" | "B" | "d" | "o" | "x" | "X"

  

  

  4、填充字元可以是'{'或'}'以外的任何Unicode程式碼點。填充字元的存在由其後的字元表示,該字元必須是對齊選項之一。如果format_spec的第二個字元不是有效的對齊選項,則假定填充字元和對齊選項都不存在。

  

  5、各種對齊選項的含義如下:

Option Meaning
'<' 強制欄位在可用空間內左對齊 ((大多數物件的預設設定).
'>' 強制欄位在可用空間內右對齊 (這是數字的預設設定).
'^'

強制欄位在可用空間內居中.

  6、請注意,除非定義了最小欄位寬度,否則欄位寬度將始終與填充它的資料大小相同。因此在這種情況下,對齊選項沒有任何意義。

 

  7、符號選項僅對數字型別有效,並且可以是以下之一:

Option Meaning
'+' 表示正負數均應使用符號,例如: +5, -2。
'-' 表示符號只能用於負數(負數預設設定顯示)。
space 表示應在正數上使用前導空格,在負數上使用減號。

  

  8、“#”選項使“替代形式”用於轉換。替代形式對於不同型別的定義不同。此選項僅對整數和浮點型別有效。對於整數,使用二進位制,八進位制或十六進位制輸出時,此選項將字首“ 0b”(“ 0B”),“ 0”或“ 0x”(“ 0X”)新增到輸出值。字首是小寫還是大寫取決於型別說明符的大小寫,例如,字首“ 0x”用於型別“ x”,“ 0X”用於“ X”。對於浮點數,替代格式會導致轉換結果始終包含小數點字元,即使後面沒有數字也是如此。通常,只有在數字後面跟隨小數點字元,這些轉換的結果才會出現。另外,對於“ g”和“ G”轉換,不會從結果中刪除部零。

  9、width是定義最小欄位寬度的十進位制整數。如果未指定,則欄位寬度將由內容確定。

  10、在寬度欄位前面加上零('0'),字元可啟用數字型別的符號識別0填充.它強制將填充內容放置在符號或基數(如果有)之後但在數字之前。這用於以“ +000000120”形式列印欄位。此選項僅對數字型別有效,並且對無窮大和NaN的格式無效。

  11、precision是一個十進位制數字,表示以'f'和'F'格式設定的浮點值在小數點後應顯示多少位數,用'g'或'G'格式化的浮點值小數點前後。對於非數字型別,該欄位指示最大欄位大小,換句話說,欄位內容中將使用多少個字元。整數,字元,布林值和指標值不允許使用精度。

  12、type欄位決定了應如何顯示資料。

  13、可用的字串表示型別為:

Type   Meaning
's' 字串格式。字串的預設型別,可以省略
none 與's'相同

  

  14、可用的字元顯示型別為:

Type Meaning
'c' 字元格式。字元的預設型別,可以省略。
none 與'c'相同

  

  

  15、可用的整數表示型別為:

Type Meaning
'b' 二進位制格式。輸出以2為進位制的數字。在此型別中使用'#'選項,會將字首“ 0b”新增到輸出值中。value.
'B' 二進位制格式。輸出以2為進位制的數字。對此型別使用'#'選項,可在輸出值中新增字首“ 0B”。
'd' 十進位制整數。輸出以10為進位制的數字。
'0' 八進位制格式。輸出以8為進位制的數字。
'x' 十六進位制格式。輸出以16為進位制的數字,對9以上的數字使用小寫字母。將'#'選項與該型別一起使用時,會將字首“ 0x”新增到輸出值中。
'X' 十六進位制格式。輸出以16為進位制的數字,對9以上的數字使用大寫字母。將'#'選項與該型別一起使用時,會將字首“ 0X”新增到輸出值中。
'L' 特定於語言環境的格式。這與'd'相同,除了它使用當前的語言環境設定來插入適當的數字分隔符。
none 與 'd' 相同

  

  16、整數表示型別也可以與字元和布林值一起使用。如果未指定輸出型別,布林值使用文字表示形式設定為true或false,

  17、浮點值的可用顯示型別為:

Type Meaning
'a' 十六進位制浮點格式。列印以16為底的數字,字首為“ 0x”,小寫字母表示9以上的數字。使用'p'表示指數。
'A' 與 'a' 相同,不同之處在於它使用大寫字母作為字首,數字大於9並表示指數。
'e' 指數表示法。使用字母“ e”以科學計數法列印數字以表示指數。
'E' 指數表示法。與'e'相同,除了它使用大寫字母'E'作為分隔符。
'f' 固定點。將數字顯示為定點數字。
'F' 固定點。與'f'相同,但是將nan轉換為NAN,將inf轉換為INF。
'g' 通用格式。對於給定的精度p> = 1,這會將數字四捨五入為p個有效數字,然後根據結果的大小以定點格式或科學計數法格式化結果。精度0等同於精度1。
'G' 通用格式。與“ g”相同,但如果數字太大則切換到 'E'。無限大和NaN的表示也都是大寫的。
'L' 特定於語言環境的格式。這與'g'相同,只是它使用當前的語言環境設定來插入適當的數字分隔符。
none 與“'g'相似,不同之處在於定點表示法在使用時,其小數點後至少有一位數字。預設精度與表示特定值所需的精度一樣高。

  

  

  18、指標的可用顯示型別為:

Type Meaning
'p' 指標格式。這是指標的預設型別,可以省略。
none 與 'p'相同

D、格式範例

  本節包含格式語法的示例以及與printf格式的比較。

  1、大多數情況下,語法類似於printf格式,加上 {} 和 :代替%。例如,“%03.2f”可以轉換為“ {:03.2f}”。

  2、新格式的語法還支援新的和不同的選項,如以下示例所示。

    2.1、按位置訪問引數:

fmt::format("{0}, {1}, {2}", 'a', 'b', 'c');
// Result: "a, b, c"
fmt::format("{}, {}, {}", 'a', 'b', 'c');
// Result: "a, b, c"
fmt::format("{2}, {1}, {0}", 'a', 'b', 'c');
// Result: "c, b, a"
fmt::format("{0}{1}{0}", "abra", "cad");  
// Result: "abracadabra"

    

    2.2、對齊文字並指定寬度:

fmt::format("{:<30}", "left aligned");
// Result: "left aligned                  "
fmt::format("{:>30}", "right aligned");
// Result: "                 right aligned"
fmt::format("{:^30}", "centered");
// Result: "           centered           "
fmt::format("{:*^30}", "centered");  // use '*' as a fill char
// Result: "***********centered***********"

    

    2.3、動態寬度:

fmt::format("{:<{}}", "left aligned", 30);
// Result: "left aligned   

    2.4、動態精度:

fmt::format("{:.{}f}", 3.14, 1);
// Result: "3.1"

    2.5、%+ f,%-f和%f並指定符號:

fmt::format("{:+f}; {:+f}", 3.14, -3.14);  // show it always
// Result: "+3.140000; -3.140000"
fmt::format("{: f}; {: f}", 3.14, -3.14);  // show a space for positive numbers
// Result: " 3.140000; -3.140000"
fmt::format("{:-f}; {:-f}", 3.14, -3.14);  // show only the minus -- same as '{:f}; {:f}'
// Result: "3.140000; -3.140000"

  

    2.6、%x和%o並將值轉換為不同的進位制:

fmt::format("int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
// Result: "int: 42;  hex: 2a;  oct: 52; bin: 101010"
// with 0x or 0 or 0b as prefix:
fmt::format("int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}", 42);
// Result: "int: 42;  hex: 0x2a;  oct: 052;  bin: 0b101010"

    2.7、用字首填充十六進位制位元組,並始終列印兩個十六進位制字元:

fmt::format("{:#04x}", 0);
// Result: "0x00"

    2.8、使用Unicode填充的方框圖:

fmt::print(
  "┌{0:─^{2}}┐\n"
  "│{1: ^{2}}│\n"
  "└{0:─^{2}}┘\n", "", "Hello, world!", 20);

    輸出結果:

┌────────────────────┐
│   Hello, world!    │
└────────────────────┘

    2.9、使用特定於型別的格式:  

#include <fmt/chrono.h>

auto t = tm();
t.tm_year = 2010 - 1900;
t.tm_mon = 6;
t.tm_mday = 4;
t.tm_hour = 12;
t.tm_min = 15;
t.tm_sec = 58;
fmt::print("{:%Y-%m-%d %H:%M:%S}", t);
// Prints: 2010-08-04 12:15:58    

  2.10、使用逗號作為千位分隔符:

#include <fmt/locale.h>

auto s = fmt::format(std::locale("en_US.UTF-8"), "{:L}", 1234567890);
// s == "1,234,567,890"

------------ 完-------------

  可見fmt的強大之處,類比python的格式化。 c++傳統的格式化也該掃進歷史的垃圾桶了。

  還等什麼,趕緊試試吧。