0

C ++でこれを行うための最良の方法(短く、標準ライブラリを使用し、理解しやすい)は何ですか?

std::string s = magic_command("%4.2f", 123.456f)
  • 長さの制限なし(char s [1000] = ...)
  • ここで、「%4.2f」は任意のc形式の文字列です(たとえば、printfに指定されます)。

私は純粋なcのために提案されたsnprintfmallocコンボを知っています

長さが不明なフォーマット済みデータを文字列に書き込む(Cプログラミング)

しかし、C ++でこれを行うためのより良い、より冗長でない方法はありますか?

私はまた、で提案されているstd::ostringstreamメソッドを知っています

C++でfloatをstd::stringに変換します

しかし、「%4.2f」などのac形式の文字列を渡したいので、ostringstreamでこれを行う方法が見つかりませんでした。

4

5 に答える 5

8

Boost.Formatを試すことができます:

std::string s = boost::str(boost::format("%4.2f") % 123.456f);

標準には含まれていませんが、Boost は非標準ライブラリが取得できる標準とほぼ同じです。

于 2012-08-20T14:35:57.067 に答える
5

代わりにstd::stringstream(と組み合わせて) を使用し、後で を使用して を取得します。setprecision.str()std::string

于 2012-08-20T14:35:01.807 に答える
5

C++ はフォーマット文字列の概念を完全に放棄しているため、それを行う標準的な方法はありません。ただし、(実際にはそのバリアント)magic_commandを使用して自分で実装できます。asprintfvasprintf

*asprintfは GNU/BSD 拡張であることに注意してください。そのため、Windows には存在しません。また、このソリューションはタイプ セーフではなく、POD 型のみを受け入れます (したがって、クラス、構造体、または共用体は受け入れません)。

std::string magic_command(const std::string& format, ...)
{
    char* ptr;
    va_list args;
    va_start(args, format);
    vasprintf(&ptr, format.c_str(), args);
    va_end(args);

    std::unique_ptr<char, decltype(free)&> free_chars(ptr, free);
    return std::string(ptr);
}
于 2012-08-20T14:38:57.680 に答える
1

文字通り構文を使用して型の安全性を放棄したい場合は、をラップする小さなラッパークラスを作成しますsnprintf。小さなサイズ(たとえば2048?)のローカルの自動バッファーから始めて、1回呼び出しますsnprintf。成功した場合はstd::string、そのバッファーから作成されたものを返します。std::stringオーバーランした場合は、正しいサイズのを割り当てて、を繰り返しますsnprintf

于 2012-08-20T14:49:50.867 に答える
1

私が望むことを行う本当に標準的な方法はないように思われるため、与えられたすべての回答は適切です。私はあなたに投票し、私自身の総括的な行動を受け入れます。

  • 文字列が手でサイズを見積もるのに十分短い場合は、それを行い、見積もりに4を掛けて、静的に割り当てます。
  • stringstream + setprecision で回避できる場合は、標準なので実行してください
  • そうでない場合、snprintf/check overflow/dynamic allocation に基づいた短いヘルパー関数を書いて含めても構わないと思っている場合は、それを実行してプロジェクトの「utils」ファイルに入れます。
  • 最後に、プロジェクトにとってどの依存関係がより制限されていないかを検討します (おそらく、それらのいずれかを既に使用している可能性があります)。
    • ブーストの制限が緩い場合は、Boost.Format を使用します
    • GNU/BSD 拡張機能の制限が緩い場合は、asprintf を使用してください
于 2012-08-21T13:11:09.230 に答える