0
我正在考虑在我们的项目中提出以下作为sprintf/snprintf的替代方案。strprintf - 这个实现是否安全和便携?
其动机是消除考虑缓冲区大小的需要,并尽可能地保留原始的便利性。
std::string strprintf(const char *fromat, ...)
{
std::string s;
s.resize(128); // best guess
char *buff = const_cast<char *>(s.data());
va_list arglist;
va_start(arglist, fromat);
auto len = vsnprintf(buff, 128, fromat, arglist);
va_end(arglist);
if (len > 127)
{
va_start(arglist, fromat);
s.resize(len + 1); // leave room for null terminator
buff = const_cast<char *>(s.data());
len = vsnprintf(buff, len+1, fromat, arglist);
va_end(arglist);
}
s.resize(len);
return s; // move semantics FTW
}
此代码是否有任何固有问题?
使用示例:
auto s = strprintf("Hello %d world", 777);
*“方便的原始”* - 这是非常值得商榷的。 – StoryTeller
看起来技术上是正确的,但如果缓冲区超过128字节上限,性能似乎不是很高。它再次调用vsnprintf,使该函数花费两倍的时间。你必须权衡这里的便利性和性能。此外,您返回的字符串将被再次复制 - 这进一步影响了性能。 – Freakyy
返回值具有移动语义,所以不应该有另一个副本。 – CplusPuzzle