それが可能かどうか、また C++ クロスプラットフォーム (C99、C++0x に依存しない) で実装する方法はsnprintf
? ブーストにそのようなものはありますか?(C++ のイディオムは何に置き換えるのsnprintf(4)
だろうか?)
6 に答える
std::ostringstream
を使用する代わりになりますsnprintf
:
char buf[1024];
snprintf(buf, 1024, "%d%s", 4, "hello");
同等:
#include <sstream>
std::ostringstream s;
s << 4 << "hello";
// s.str().c_str(); // This returns `const char*` to constructed string.
boost::lexical_castもあります:
std::string s = boost::lexical_cast<std::string>(4) +
boost::lexical_cast<std::string>("hello");
はい、フォーマット文字列をサポートする Boost Format ライブラリがあります。
Boostが言及されたので、Boost.Formatに何か問題がありますか?
Qt QString classを見たいと思うかもしれません。これは、非常にオブジェクト指向の方法で必要なことを行うフォーマット関数を提供します。あなたは確かにそれをコピーして学ぶことができます.
はい、ブーストのタグが付けられた質問でQtに言及することはタブーかもしれませんが、質問はそれよりも一般的なように見えました。
snprintf
Windows/Linux/HP-UX で必要になったら。を定義snprintf_safe
し、Linux/HP-UX では を使用しsnprinf
、Windows では を使用し_snprintf
ました。_snprintf
データを格納するために必要なバイト数が最大許容サイズを超える場合、'\0' を書き込む方法が少し異なることを覚えています。だから対処する必要がありました。とにかく、それはこの種のマクロでした:
#ifdef #WIN32
int snprintf_safe()
{
// make use of _snprintf
}
#else
#define snprintf_safe snprintf
#endif
std::ostringstream
またはstd::to_string
(c++11) は代替手段として機能しますが、追加のコピーを使用せずにパフォーマンスを向上させるソリューションが必要な場合、または C++ ではなく C のみを使用する場合は、別のことを行う必要がある場合があります。
MSVC は C99 をサポートしていないため、snprintf
機能はなく、自作の
_snprintf
.
_snprintf
MSVCと公式 C99 (gcc,clang)の違いsnprintf
:
戻り値:
- MSVC: バッファー サイズがすべてを書き込むのに十分でない場合は -1 を返します (終端の null を含まない!)
- GCC: バッファが十分に大きい場合に書き込まれる文字数を返す
書き込まれたバイト:
- MSVC: できる限り書き込みます。スペースが残っていない場合は最後に NULL を書き込まないでください。
- GCC: 可能な限り書き込み、常に終了 NULL を書き込みます (例外: buffer_size=0)
興味深い%n
微妙な点:%n
コードで を使用すると、MSVC はそれを初期化したままにします! バッファサイズが小さすぎるために解析が停止した場合、GCC は、バッファが十分に大きかった場合に書き込まれるバイト数を常に書き込みます。
したがって、私の提案は、/をmysnprintf
使用して独自のラッパー関数を作成することです。これにより、両方のプラットフォームで同じ戻り値が得られ、同じバイトが書き込まれます (注意:修正がより困難です)。vsnprintf
_vsnprintf
%n