【C++】format() – C++でprintf()風の書式指定を使う
はじめに
C++で値を出力するにはストリームを使いますが、桁数設定や小数点以下の精度表示をするためにわざわざsetw()やsetprecision()する必要があるなど、マニピュレータを使用した書式指定が面倒でした。
C言語に慣れているとprintf()の書式指定方法が便利で、printf()をC++でも使いたくなるときがあります。Boostライブラリには、似たようなものが用意されていますが、このためだけにBoostをインストールするのも大掛かりです。
しかしながら、ようやくC++20においてprinf()風の書式指定ができるformat()が標準仕様に追加されました。このエントリでは、このformat()についてまとめてみました。
使い方
format()関数はprintf()と同じような形で使うことができます。戻り値はstd::stringです。
std::format(書式指定を含む文字列, 値...){}でくくった部分を値で置き換えた文字列を作成します。書式指定は省略可能です。
例
int a = 0; std::string b = "test"; std::string s = std::format("a = {}, b = {}", a, b); // "a = 0, b = test"
{}の中にprintf()のような書式指定を書くことができます。詳細な書式は以下になります。([]は省略可能の意味)
{[ID][:[[埋め文字]桁寄せ][符号][#][0][幅][.精度][L][種別]]}| 種類 | 説明 |
|---|---|
| ID | 引数の番号。何番目の引数で置換するかを表す(0~) |
| 埋め文字 | 桁数指定したときの余白を埋める文字(省略時は空白) |
| 桁寄せ | 右寄せ(>)、左寄せ(<)、中央揃え(^)を表す記号 |
| 符号 | プラス/マイナスを表示(+)、負の値でマイナスを表示(-)、正の値で空白を表示(スペース) |
# | 代替表現を使用する(例:16進表示で"0x"を表示する) |
0 | 0で埋める |
| 幅 | 表示幅 |
| 精度 | 小数点以下の表示桁数 |
| L | ロケールを考慮する |
| 種別 | 値の表現方法 |
値の表現方法とは、整数を表すdや浮動小数点数を表すf、文字列を表すsなどのことです。以下のようなものが指定可能です。
| 種別 | 意味 |
|---|---|
| d | 整数 |
| b | 2進数表示 |
| o | 8進数表示 |
| x | 16進数表示(小文字) |
| X | 16進数表示(大文字) |
| f | 実数(指数表示しない) |
| e | 実数(指数表示する) |
| g | 実数(必要に応じて指数表示する) |
| s | 文字列 |
| c | 文字 |
| p | ポインタ |
使用例
実際にformat()を使った例を示します。printf()による書式指定方法と比較しました。
#include <cstdio>
#include <format>
#include <iostream>
#include <string>
using namespace std;
int main()
{
int a = 10;
float b = 3.1415926;
unsigned char c = '\x20';
char d[] = "string";
// int型
printf("%d\n", a);
cout << format("{:d}", a) << endl;
// int型、5桁出力、0埋め、+記号表示
printf("%+05d\n", a);
cout << format("{:+05d}", a) << endl;
// float型、10桁出力、小数点以下5桁
printf("%10.5f\n", b);
cout << format("{:10.5f}", b) << endl;
// float型、指数表記
printf("%e\n", b);
cout << format("{:e}", b) << endl;
// unsigned char型、16進表示、2桁
printf("%#02x\n", c);
cout << format("{:#02x}", c) << endl;
// 文字列、10桁出力、右揃え
printf("%10s\n", d);
cout << format("{:10s}", d) << endl;
// 文字列、10桁出力、左揃え
printf("%-10s\n", d);
cout << format("{:<10s}", d) << endl;
// 文字列、10桁出力、中央揃え: printf()ではできない
cout << format("{:^10s}", d) << endl;
// bool型
cout << format("{}", true) << endl;
cout << format("{}", false) << endl;
return 0;
}出力結果
10
10
+0010
+0010
3.14159
3.14159
3.141593e+00
3.141593e+00
0x20
0x20
string
string
string
string
string
true
falseこのように比較すると、%の代わりに:で始めることと{}でくくること以外は、printf()とほぼ同じ指定で使えることがわかると思います。
まとめ
C++20で導入されたprintf()風に使える関数format()についてまとめてみました。%の代わりに:で始めることと{}でくくること以外は、printf()とほぼ同じ指定で使えます。また、stringを返すのでprintf()とsprintf()を使い分けるようなことが不要となります。
C++23以降ではさらに拡張され、vectorやmap, pairなどにも対応するようです。
(参考)



ディスカッション
コメント一覧
まだ、コメントがありません