Standard format specification (since C++20)
基本型と文字列型の場合、書式指定は Pythonの書式指定 に基づいています。
書式指定の構文は以下の通りです:
fill-and-align
(オプション)
sign
(オプション)
#
(オプション)
0
(オプション)
width
(オプション)
precision
(オプション)
L
(オプション)
type
(オプション)
|
|||||||||
sign
オプション、
#
および
0
オプションは、整数または浮動小数点の表示タイプが使用されている場合にのみ有効です。
目次 |
フィルとアライメント
fill-and-align
は任意の
fill
文字(
{
または
}
以外の任意の文字)と、それに続く
align
オプション
<
、
>
、
^
のいずれかで構成されます。
塗りつぶし文字が指定されていない場合、デフォルトでスペース文字が使用されます。Unicodeエンコーディングのフォーマット仕様では、塗りつぶし文字は単一のUnicodeスカラー値に対応する必要があります。
align オプションの意味は以下の通りです:
-
<: 書式化された引数を利用可能なスペースの開始位置に強制的に配置します。これは、非整数かつ非浮動小数点の表示型が使用された場合のデフォルトです。 -
>: 書式化された引数を利用可能なスペースの終了位置に強制的に配置します。これは、整数または浮動小数点の表示型が使用された場合のデフォルトです。 -
^: 書式化された引数を利用可能なスペースの中央に強制的に配置します。 ⌊
⌋ 個の文字を前に挿入し、 ⌈n 2
⌉ 個の文字を後に挿入します。n 2
各ケースにおいて、 n は最小フィールド幅( width で指定)とフォーマット済み引数の 推定幅 との差、または差が0未満の場合は0です。
#include <cassert> #include <format> int main() { char c = 120; assert(std::format("{:6}", 42) == " 42"); assert(std::format("{:6}", 'x') == "x "); assert(std::format("{:*<6}", 'x') == "x*****"); assert(std::format("{:*>6}", 'x') == "*****x"); assert(std::format("{:*^6}", 'x') == "**x***"); assert(std::format("{:6d}", c) == " 120"); assert(std::format("{:6}", true) == "true "); }
符号、#、および 0
sign オプションは以下のいずれかを指定できます:
-
+: 非負数および負数の両方で符号を使用することを示します。非負数の場合、出力値の前に+記号が挿入されます。 -
-: 負数のみで符号を使用することを示します(これはデフォルトの動作です)。 - スペース: 非負数の場合は先頭にスペースを、負数の場合はマイナス記号を使用することを示します。
負のゼロは負の数として扱われます。
浮動小数点の無限大とNaNに sign オプションが適用されます。
#include <cassert> #include <format> #include <limits> int main() { double inf = std::numeric_limits<double>::infinity(); double nan = std::numeric_limits<double>::quiet_NaN(); assert(std::format("{0:},{0:+},{0:-},{0: }", 1) == "1,+1,1, 1"); assert(std::format("{0:},{0:+},{0:-},{0: }", -1) == "-1,-1,-1,-1"); assert(std::format("{0:},{0:+},{0:-},{0: }", inf) == "inf,+inf,inf, inf"); assert(std::format("{0:},{0:+},{0:-},{0: }", nan) == "nan,+nan,nan, nan"); }
#
オプションは、変換に
代替形式
を使用することを引き起こします。
-
整数型の場合、2進数、8進数、または16進数の表示形式が使用されるとき、代替形式は符号文字(スペースの場合もある)がある場合はその後に接頭辞(
0b、0、または0x)を出力値に挿入し、それ以外の場合は出力値の前に追加します。 -
浮動小数点型の場合、代替形式により有限値の変換結果には、たとえその後ろに数字が続かなくても、常に小数点文字が含まれます。通常、これらの変換の結果には数字が続く場合にのみ小数点文字が表示されます。さらに、
gおよびG変換では、末尾のゼロが結果から削除されません。
0
オプションは、無限大またはNaNに適用される場合を除き、フィールド幅まで先行ゼロ(符号または基数の表示の後)でフィールドをパディングします。
0
文字と
align
オプションの両方が存在する場合、
0
文字は無視されます。
#include <cassert> #include <format> int main() { char c = 120; assert(std::format("{:+06d}", c) == "+00120"); assert(std::format("{:#06x}", 0xa) == "0x000a"); assert(std::format("{:<06}", -42) == "-42 "); // '<' のため 0 は無視される }
幅と精度
width
は正の10進数、またはネストされた置換フィールド(
{}
または
{
n
}
)のいずれかです。存在する場合、最小フィールド幅を指定します。
precision
はドット(
.
)に続き、非負の10進数またはネストされた置換フィールドのいずれかです。このフィールドは精度または最大フィールドサイズを示します。浮動小数点型と文字列型でのみ使用できます。
- 浮動小数点型の場合、このフィールドは書式設定の精度を指定します。
- 文字列型の場合、出力にコピーされる文字列の接頭辞の推定幅( 後述 を参照)の上限を提供します。Unicodeエンコーディングの文字列の場合、出力にコピーされるテキストは、推定幅が精度以下となる完全な拡張書記素クラスタの最長接頭辞です。
ネストされた置換フィールドが width または precision に使用され、対応する引数が 整数型 (C++23まで) 標準の符号付きまたは符号なし整数型 (C++23以降) でない場合、または負の値である場合、 std::format_error 型の例外がスローされます。
float pi = 3.14f; assert(std::format("{:10f}", pi) == " 3.140000"); // 幅 = 10 assert(std::format("{:{}f}", pi, 10) == " 3.140000"); // 幅 = 10 assert(std::format("{:.5f}", pi) == "3.14000"); // 精度 = 5 assert(std::format("{:.{}f}", pi, 5) == "3.14000"); // 精度 = 5 assert(std::format("{:10.5f}", pi) == " 3.14000"); // 幅 = 10, 精度 = 5 assert(std::format("{:{}.{}f}", pi, 10, 5) == " 3.14000"); // 幅 = 10, 精度 = 5 auto b1 = std::format("{:{}f}", pi, 10.0); // 例外発生: 幅が整数型ではない auto b2 = std::format("{:{}f}", pi, -10); // 例外発生: 幅が負の値 auto b3 = std::format("{:.{}f}", pi, 5.0); // 例外発生: 精度が整数型ではない
文字列の幅は、ターミナルで表示するのに適した桁位置の推定数として定義されます。
幅の計算目的において、文字列は実装定義のエンコーディングにあると仮定されます。幅の計算方法は未規定ですが、Unicodeエンコーディングの文字列の場合、実装は文字列の幅をその 拡張書記素クラスター の最初のコードポイントの推定幅の合計として見積もるべきです。以下のコードポイントについては推定幅が2となり、それ以外の場合は1となります:
-
Unicodeプロパティ
East_Asian_Widthの値が全角(F)または広角(W)である任意のコードポイント - U+4DC0 - U+4DFF(易経六十四卦記号)
- U+1F300 – U+1F5FF(その他の記号及び絵文字)
- U+1F900 – U+1F9FF(補助記号及び絵文字)
#include <cassert> #include <format> int main() { assert(std::format("{:.^5s}", "🐱") == ".🐱.."); assert(std::format("{:.5s}", "🐱🐱🐱") == "🐱🐱"); assert(std::format("{:.<5.5s}", "🐱🐱🐱") == "🐱🐱."); }
L (ロケール固有のフォーマット)
L
オプションは、ロケール固有の形式を使用するようにします。このオプションは算術型に対してのみ有効です。
- 整数型の場合、ロケール固有の形式は、コンテキストのロケールに従って適切な桁区切り文字を挿入します。
- 浮動小数点型の場合、ロケール固有の形式は、コンテキストのロケールに従って適切な桁区切り文字と基数区切り文字を挿入します。
-
boolのテキスト表現の場合、ロケール固有の形式は std::numpunct::truename または std::numpunct::falsename から取得したかのように適切な文字列を使用します。
型
type オプションは、データの表示方法を決定します。
利用可能な文字列プレゼンテーション型は以下の通りです:
-
none,
s: 文字列を出力にコピーします。
|
(C++23以降) |
char 、 wchar_t 、および bool 以外の整数型で利用可能な整数表現型は以下の通りです:
-
b: バイナリ形式。 std:: to_chars ( first, last, value, 2 ) を呼び出した場合と同様の出力を生成します。基数プレフィックスは0bです。 -
B:bと同じですが、基数プレフィックスが0Bである点が異なります。 -
c: 文字 static_cast < CharT > ( value ) を出力にコピーします。ここでCharTはフォーマット文字列の文字型です。値がCharTの表現可能な値の範囲内にない場合、 std::format_error をスローします。 -
d: 10進数形式。 std:: to_chars ( first, last, value ) を呼び出した場合と同様の出力を生成します。 -
o: 8進数形式。 std:: to_chars ( first, last, value, 8 ) を呼び出した場合と同様の出力を生成します。基数プレフィックスは、対応する引数値が非ゼロの場合は0、それ以外の場合は空です。 -
x: 16進数形式。 std:: to_chars ( first, last, value, 16 ) を呼び出した場合と同様の出力を生成します。基数プレフィックスは0xです。 -
X:xと同じですが、9を超える数字に大文字を使用し、基数プレフィックスが0Xである点が異なります。 -
指定なし:
dと同じです。
利用可能な char および wchar_t プレゼンテーション型は以下の通りです:
-
none、
c: 文字を出力にコピーします。 -
b、B、d、o、x、X: 整数表現型を使用し、値 static_cast < unsigned char > ( value ) または static_cast < std:: make_unsigned_t < wchar_t >> ( value ) をそれぞれ使用します。
|
(C++23以降) |
利用可能な bool プレゼンテーションタイプは以下の通りです:
-
none、
s:テキスト表現(trueまたはfalse、またはロケール固有の形式)を出力にコピーします。 -
b、B、d、o、x、X:値 static_cast < unsigned char > ( value ) に対して整数表現型を使用します。
利用可能な浮動小数点表現型は以下の通りです:
-
a: precision が指定されている場合、 std:: to_chars ( first, last, value, std :: chars_format :: hex , precision ) を呼び出したかのように出力を生成する。それ以外の場合は、 std:: to_chars ( first, last, value, std :: chars_format :: hex ) を呼び出したかのように出力を生成する。 -
A:aと同じだが、9を超える桁に大文字を使用し、指数を示すためにPを使用する点が異なる。 -
e: std:: to_chars ( first, last, value, std :: chars_format :: scientific , precision ) を呼び出したかのように出力を生成する。ここで precision は指定された精度、または精度が指定されていない場合は6である。 -
E:eと同じだが、指数を示すためにEを使用する点が異なる。 -
f,F: std:: to_chars ( first, last, value, std :: chars_format :: fixed , precision ) を呼び出したかのように出力を生成する。ここで precision は指定された精度、または精度が指定されていない場合は6である。 -
g: std:: to_chars ( first, last, value, std :: chars_format :: general , precision ) を呼び出したかのように出力を生成する。ここで precision は指定された精度、または精度が指定されていない場合は6である。 -
G:gと同じだが、指数を示すためにEを使用する点が異なる。 - なし: precision が指定されている場合、 std:: to_chars ( first, last, value, std :: chars_format :: general , precision ) を呼び出したかのように出力を生成する。ここで precision は指定された精度である。それ以外の場合は、 std:: to_chars ( first, last, value ) を呼び出したかのように出力を生成する。
小文字のプレゼンテーションタイプの場合、無限大とNaNはそれぞれ
inf
と
nan
としてフォーマットされます。
大文字のプレゼンテーションタイプの場合、無限大とNaNはそれぞれ
INF
と
NAN
としてフォーマットされます。
| std::format 指定子 | std::chars_format | 対応する std::printf 指定子 |
|---|---|---|
a
,
A
|
std::chars_format::hex |
a
,
A
(ただし
std::format
は先頭の
0x
または
0X
を出力しない)
|
e
,
E
|
std::chars_format::scientific |
e
,
E
|
f
,
F
|
std::chars_format::fixed |
f
,
F
|
g
,
G
|
std::chars_format::general |
g
,
G
|
| なし | std::chars_format::general が精度指定されている場合、それ以外の場合は最短のラウンドトリップ形式 |
g
が精度指定されている場合。それ以外の場合は対応する指定子はない。
|
利用可能なポインタ表示型( std::nullptr_t でも使用されます)は以下の通りです:
-
none,
p: std::uintptr_t が定義されている場合、 std:: to_chars ( first, last, reinterpret_cast < std:: uintptr_t > ( value ) , 16 ) を呼び出したかのような出力を生成し、出力に接頭辞0xを追加する。それ以外の場合、出力は実装定義となる。
|
(C++26以降) |
エスケープされた文字と文字列のフォーマット文字や文字列は、デバッグやロギングにより適した形式にするために エスケープ された形式でフォーマットできます。 エスケープは以下のように行われます:
文字列のエスケープされた文字列表現は、上記のように文字列内のコード単位シーケンスをエスケープし、結果をダブルクォートで囲むことで構築されます。 文字のエスケープされた表現は、上記のようにエスケープし、結果をシングルクォートで囲むことで構築されます。
このコードを実行
#include <print> int main() { std::println("[{:?}]", "h\tllo"); // prints: ["h\tllo"] std::println("[{:?}]", "Спасибо, Виктор ♥!"); // prints: ["Спасибо, Виктор ♥!"] std::println("[{:?}] [{:?}]", '\'', '"'); // prints: ['\'', '"'] // The following examples assume use of the UTF-8 encoding std::println("[{:?}]", std::string("\0 \n \t \x02 \x1b", 9)); // prints: ["\u{0} \n \t \u{2} \u{1b}"] std::println("[{:?}]", "\xc3\x28"); // invalid UTF-8 // prints: ["\x{c3}("] std::println("[{:?}]", "\u0301"); // prints: ["\u{301}"] std::println("[{:?}]", "\\\u0301"); // prints: ["\\\u{301}"] std::println("[{:?}]", "e\u0301\u0323"); // prints: ["ẹ́"] } |
(C++23以降) |
注記
ほとんどの場合、構文は従来の
%
フォーマットと類似しており、
{}
の追加と、
%
の代わりに
:
が使用される点が異なります。例えば、
"%03.2f"
は
"{:03.2f}"
に変換できます。
| 機能テスト マクロ | 値 | 標準 | 機能 |
|---|---|---|---|
__cpp_lib_format_uchar
|
202311L
|
(C++20)
(DR) |
コードユニットの符号なし整数としてのフォーマット |
欠陥報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 3721 | C++20 |
標準フォーマット仕様において幅フィールドに
ゼロは許可されない |
置換フィールド経由で指定された場合は
ゼロが許可される |
| P2909R4 | C++20 |
char
または
wchar_t
が範囲外の符号なし整数値として
フォーマットされる可能性があった |
コード単位はそのようなフォーマットの前に
対応する符号なし型に変換される |