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++傳統的格式化也該掃進歷史的垃圾桶了。
還等什麼,趕緊試試吧。