17

std::string一連の引数を渡してフォーマットすることは可能ですか?

現在、私はこのように文字列をフォーマットしています:

string helloString = "Hello %s and %s";
vector<string> tokens; //initialized vector of strings
const char* helloStringArr = helloString.c_str();
char output[1000];
sprintf_s(output, 1000, helloStringArr, tokens.at(0).c_str(), tokens.at(1).c_str());

ただし、ベクトルのサイズは実行時に決定されます。sprintf_s引数のコレクションを取り、std :: string / char *をフォーマットするのと同様の関数はありますか?私の開発環境はMSVisualC ++2010Expressです。

編集: 私は似たようなことを達成したいと思います:

sprintf_s(output, 1000, helloStringArr, tokens);
4

3 に答える 3

13

sprintfのような機能を実現するための最もC++風の方法は、stringstreamsを使用することです。

コードに基づく例を次に示します。

#include <sstream>

// ...

std::stringstream ss;
std::vector<std::string> tokens;
ss << "Hello " << tokens.at(0) << " and " << tokens.at(1);

std::cout << ss.str() << std::endl;

かなり便利ですね。

もちろん、さまざまなsprintfフラグを置き換えるIOStream操作の利点を最大限に活用できます。参照については、http: //www.fredosaurus.com/notes-cpp/io/omanipulators.htmlを参照してください。

より完全な例:

#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>

int main() {
  std::stringstream s;
  s << "coucou " << std::setw(12) << 21 << " test";

  std::cout << s.str() << std::endl;
  return 0;
}

印刷するもの:

coucou           21 test

編集

OPが指摘しているように、この方法では可変個引数の引数を使用できません。これは、ストリームがベクトルを反復処理し、プレースホルダーに従ってデータを挿入できるようにする事前に作成された「テンプレート」文字列がないためです。

于 2011-02-22T10:07:55.790 に答える
9

引数を1つずつフィードできるため、 Boost.Formatライブラリを使用してこれを行うことができます。

printfこれにより、すべての引数を一度に渡さなければならないファミリとはまったく異なり、実際に目標を達成できます(つまり、コンテナ内の各アイテムに手動でアクセスする必要があります)。

例:

#include <boost/format.hpp>
#include <string>
#include <vector>
#include <iostream>
std::string format_range(const std::string& format_string, const std::vector<std::string>& args)
{
    boost::format f(format_string);
    for (std::vector<std::string>::const_iterator it = args.begin(); it != args.end(); ++it) {
        f % *it;
    }
    return f.str();
}

int main()
{
    std::string helloString = "Hello %s and %s";
    std::vector<std::string> args;
    args.push_back("Alice");
    args.push_back("Bob");
    std::cout << format_range(helloString, args) << '\n';
}

ここから作業したり、テンプレート化したりできます。

ベクトルに正確な量の引数が含まれていない場合は、例外(ドキュメントを参照)がスローされることに注意してください。それらの処理方法を決定する必要があります。

于 2011-02-22T14:19:14.873 に答える
1

出力バッファを手動で処理する必要がないようにしたい場合は、boost::formatライブラリが役立つ場合があります

単純なベクトルを入力として使用する場合、どうしますtokens.size()<2か?いずれにせよ、ベクトルが要素0と1にインデックスを付けるのに十分な大きさであることを確認する必要はありませんか?

于 2011-02-22T10:11:22.110 に答える