C/C++C++20フォーマットライブラリstd::format

17250 ワード

説明
テキストフォーマットライブラリはprintf関数ファミリーの安全で拡張可能な代替品を提供します.既存のC++I/Oストリームライブラリを意図的に補充し、ユーザー定義タイプのリロードされたストリームに演算子を挿入するなど、インフラストラクチャを多重化します.
ヘッダファイル
#include 

関数の定義
template<class... Args>
std::string format(std::string_view fmt, const Args&... args);

template<class... Args>
std::wstring format(std::wstring_view fmt, const Args&... args);

template<class... Args>
std::string format(const std::locale& loc, std::string_view fmt, const Args&... args);

template<class... Args>
std::wstring format(const std::locale& loc, std::wstring_view fmt, const Args&... args);

フォーマット文字列fmtに従ってargsをフォーマットし、stringの結果として返します.locが存在する場合は、ローカル環境固有のフォーマットに使用されます.
パラメータの説明
fmt-フォーマット文字列を表す文字列ビュー.
フォーマット文字列は、次の内容で構成されます.
  • 通常文字({と}を除く)は、出力
  • に変更なくコピーされる.
  • エスケープシーケンス{{と}}は、出力においてそれぞれ{と}
  • に置き換えられる.
  • 置換ドメイン
  • 各置換ドメインには、次のフォーマットがあります.
  • に導入された{文字
  • (オプション)arg-id、非負数
  • (オプション)コロン(:)は、フォーマットの説明
  • に従います.
  • で終了した}文字
  • arg-idは、その値をフォーマットするargsのパラメータの下付き記号を指定します.arg-idを省略すると、パラメータは順番に使用されます.フォーマット文字列のarg-idはすべて存在するか、またはすべて省略する必要があります.手動と自動で下付き文字を混合するのはエラーです.フォーマット説明は、対応するパラメータによって特化されたstd::formatterによって定義されます.
  • 基本タイプおよび標準文字列タイプについて、フォーマット説明は標準フォーマット説明
  • である.
  • 標準日付および時間タイプについて、フォーマットはchronoフォーマットの説明
  • である.
  • ユーザ定義タイプについて、フォーマット説明ユーザ定義std::formatter特化決定
  • .
    args...-フォーマットするパラメータ
    loc-ローカル環境固有のフォーマットに使用されるstd::locale
    戻り値
    フォーマット結果を保持するstringオブジェクト.
    異常
    fmtが提供するパラメータに対して合法的なフォーマット文字列でない場合std::format_を投げ出すerror .フォーマットで放出された例外が伝播します.フォーマット文字列よりも多くのパラメータを指定するのはエラーではありません.
    std::format("{} {}!", "Hello", "world", "something"); // OK :   "Hello world!"
    

    塗りつぶしと位置合わせ
    基本フォーマット:
         (  )   (  ) #(  ) 0(  )   (  )   (  ) L(  )   (  )
    

    [塗りつぶしと位置合わせ](Fill and Align)は、任意の{または}以外の文字であるオプションの塗りつぶし文字です.位置合わせオプション<、>、^の1つです.位置合わせオプションの意味は次のとおりです.
  • <:ドメインを使用可能なスペース内で左揃えにします.これは、非整数非浮動小数点表示タイプを使用する場合にデフォルトです.
  • >:ドメインを使用可能なスペース内で右揃えにします.これは、整数または浮動小数点表示タイプを使用する場合にデフォルトです.
  • ^:強制ドメインは使用可能な空間の中央にあり、値の前にn/2を挿入することによって文字全体を下に取り、後ろにn/2を挿入して文字全体を上に取り、ここでnは挿入する総文字数である.
  • char c = 120;
    auto s0 = std::format("{:6}", 42);    // s0     "    42"
    auto s1 = std::format("{:6}", 'x');   // s1     "x     "
    auto s2 = std::format("{:*<6}", 'x'); // s2     "x*****"
    auto s3 = std::format("{:*>6}", 'x'); // s3     "*****x"
    auto s4 = std::format("{:*^6}", 'x'); // s4     "**x***"
    auto s5 = std::format("{:6d}", c);    // s5     "   120"
    auto s6 = std::format("{:6}", true);  // s6     "true  "
    

    記号、#と0
    シンボルオプションは、次のいずれかです.
  • +:シンボルが非負数および負数で一緒に使用されるべきであることを示します.負数以外の出力値の前に+を挿入します.
  • -:シンボルが負の数にのみ使用されるべきであることを示します(これはデフォルトの動作です).
  • スペース:負以外の値には先頭スペース、負の値には負の番号が使用されます.

  • 負のゼロは負の数として扱われる.記号オプションは浮動小数点無限大とNaNに適用されます.
    double inf = std::numeric_limits<double>::infinity();
    double nan = std::numeric_limits<double>::quiet_NaN();
    auto s0 = std::format("{0:},{0:+},{0:-},{0: }", 1);   // s0     "1,+1,1, 1"
    auto s1 = std::format("{0:},{0:+},{0:-},{0: }", -1);  // s1     "-1,-1,-1,-1"
    auto s2 = std::format("{0:},{0:+},{0:-},{0: }", inf); // s2     "inf,+inf,inf, inf"
    auto s3 = std::format("{0:},{0:+},{0:-},{0: }", nan); // s3     "nan,+nan,nan, nan"
    

    formatter-カスタムタイプ拡張
    formatterの使用可能な特化は、所与のタイプに対してフォーマット規則を定義する.特化を有効にするには、フォーマットの要件を満たす必要があります.特に、メンバー関数または関数テンプレートparseとformatを定義します.
    #include 
    #include 
    	 
    //    T    
    template<class T>
    struct Box {
         
        T value;
    };
     
    //                  Box
    template<class T, class CharT>
    struct std::formatter<Box<T>, CharT> : std::formatter<T, CharT> {
         
        //       parse()
     
        //                 format()
        template<class FormatContext>
        auto format(Box<T> t, FormatContext& fc) {
         
            return std::formatter<T, CharT>::format(t.value, fc);
        }
    };
     
    int main() {
         
        Box<int> v = {
          42 };
        std::cout << std::format("{:#x}", v);
    }
    

    出力:
    0x2a
    

    参照先:https://zh.cppreference.com/w/cpp/utility/format