One option is that the temp buffer starts some known size and then increases it if it is not enough vsnprintf. Is there a better approach? Thanks
You can use vasprintf(), but it makes unnecessary heap allocation - it is unlikely to be faster on average. Using alloca, you can avoid heaps. Or you can write directly in the return string: NRVO should avoid copying, and with the semantics of movement C ++ 11 limits the cost of sans-NRVO to a few sets of pointers.
#include <cstdio>
#include <cstdarg>
#include <alloca.h>
#include <string>
#include <iostream>
std::string stringf(const char* format, ...)
{
va_list arg_list;
va_start(arg_list, format);
char short_buf[256];
const size_t needed = vsnprintf(short_buf, sizeof short_buf,
format, arg_list) + 1;
if (needed <= sizeof short_buf)
return short_buf;
std::string result(needed, ' ');
vsnprintf(result.data(), needed, format, arg_list);
return result;
OR
char* p = static_cast<char*>(alloca(needed));
vsnprintf(p, needed, format, arg_list);
return p;
}
int main()
{
std::string s = stringf("test '%s', n %8.2f\n", "hello world", 3.14);
std::cout << s;
}
A simpler and initially faster option:
std::string result(255, ' ');
const size_t needed = vsnprintf(result.data(), result.size() + 1,
format, arg_list);
result.resize(needed);
if (needed > 255)
vsnprintf(result.data(), needed + 1, format, arg_list);
return result;
, 256 , : , /. , [ shrink_to_fit] http://en.cppreference.com/w/cpp/string/basic_string/shrink_to_fit), , ( " " ). , char.