std::stringでprintfのような書式指定を行う方法 (C++11版)

C++11を使うと綺麗に実装できます

まず format() というテンプレート関数を作ります.C++11で新しく導入された,可変引数テンプレート,および std::snprintf() を使います.

#include <string>
#include <cstdio>
#include <vector>

template <typename ... Args>
std::string format(const std::string& fmt, Args ... args )
{
    size_t len = std::snprintf( nullptr, 0, fmt.c_str(), args ... );
    std::vector<char> buf(len + 1);
    std::snprintf(&buf[0], len + 1, fmt.c_str(), args ... );
    return std::string(&buf[0], &buf[0] + len);
}

あとはこれを呼ぶだけ.

#include <iostream>
int
main()
{
    std::cout << format("%e", 1./3)  << std::endl;
    return 0;
}

C++ で "%d" のような書式指定を行うには boost::format を使う方法もあります

#include <iostream>
#include <boost/format.hpp>

int main()
{
    std::cout <<
        boost::format("%2% %1%") % 3 % std::string("Hello")
    << std::endl;
}

という感じになります.しかしこのコードは

  • 慣れてない人は全く読めない(悪い意味でboost的)
  • boost のインストールが少々面倒(boostのbcpを知っていれば少しは楽ですが,再配布や納品時,ライセンスまで考えるとやはり面倒)

という点が不便でした.

一方,C++11版なら,

  • コンパクト
  • 移植性もバッチリ(追加ライブラリ不要.visual studio, clang, gccどれでも標準ライブラリだけで動きます)

という感じで使い勝手がいいかと思います.