Namespaces
Variants

Standard format specification (since C++20)

From cppreference.net

基本型と文字列型の場合、書式指定は 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 を追加する。それ以外の場合、出力は実装定義となる。
  • P : p と同じですが、9を超える数字には大文字が使用され、基数プレフィックスは 0X になります。
(C++26以降)


エスケープされた文字と文字列のフォーマット

文字や文字列は、デバッグやロギングにより適した形式にするために エスケープ された形式でフォーマットできます。

エスケープは以下のように行われます:

  • 整形式のコード単位シーケンスで文字 C をエンコードする各シーケンスについて:
  • もし C が以下の表の文字のいずれかである場合、対応するエスケープシーケンスが使用されます。
文字 エスケープシーケンス 注記
水平タブ(ASCIIエンコーディングのバイト0x09) \t
改行 - ニューライン(ASCIIエンコーディングのバイト0x0a) \n
キャリッジリターン(ASCIIエンコーディングのバイト0x0d) \r
ダブルクォート(ASCIIエンコーディングのバイト0x22) \" 出力がダブルクォート文字列の場合のみ使用
シングルクォート(ASCIIエンコーディングのバイト0x27) \' 出力がシングルクォート文字列の場合のみ使用
バックスラッシュ(ASCIIエンコーディングのバイト0x5c) \\
  • それ以外の場合、 C がスペース文字(ASCIIエンコーディングのバイト0x20)ではなく、かつ以下のいずれかの条件を満たす場合:
  • 関連付けられた文字エンコーディングがUnicodeエンコーディングであり、かつ
  • C がUnicodeプロパティ General_Category の値が Separator ( Z ) または Other ( C ) のグループにあるUnicodeスカラー値に対応する場合、または
  • C が直前にエスケープされていない文字がなく、 C がUnicodeプロパティ Grapheme_Extend=Yes を持つUnicodeスカラー値に対応する場合
  • 関連付けられた文字エンコーディングがUnicodeエンコーディングではなく、 C が実装定義のセパレータまたは非表示文字のセットのいずれかである場合
エスケープシーケンスは \u{ hex-digit-sequence } となり、ここで hex-digit-sequence C の小文字の16進数を使用した最短の16進数表現です。
  • それ以外の場合、 C はそのままコピーされます。
  • シフトシーケンスであるコード単位シーケンスは、出力および文字列のさらなるデコードに対して未指定の効果を持ちます。
  • その他のコード単位(つまり、不正なコード単位シーケンス内のもの)はそれぞれ \x{ hex-digit-sequence } で置き換えられ、ここで hex-digit-sequence はコード単位の小文字の16進数を使用した最短の16進数表現です。

文字列のエスケープされた文字列表現は、上記のように文字列内のコード単位シーケンスをエスケープし、結果をダブルクォートで囲むことで構築されます。

文字のエスケープされた表現は、上記のようにエスケープし、結果をシングルクォートで囲むことで構築されます。

Compiler Explorer デモ

#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 が範囲外の符号なし整数値として
フォーマットされる可能性があった
コード単位はそのようなフォーマットの前に
対応する符号なし型に変換される