I have to format std::string with sprintf and send it into file stream. How can I do this?
My two cents on this very popular question.
To quote the manpage of printf-like functions:
Upon successful return, these functions return the number of characters printed (excluding the null byte used to end output to strings).
The functions snprintf() and vsnprintf() do not write more than size bytes (including the terminating null byte ('\0')). If the output was truncated due to this limit then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available. Thus, a return value of size or more means that the output was truncated.
In other words, a sane C++11 implementation should be the following:
#include
#include
template
std::string fmt (const std::string &fmt, Ts... vs)
{
char b;
size_t required = std::snprintf(&b, 0, fmt.c_str(), vs...) + 1;
// See comments: the +1 is necessary, while the first parameter
// can also be set to nullptr
char bytes[required];
std::snprintf(bytes, required, fmt.c_str(), vs...);
return std::string(bytes);
}
It works quite well :)
Variadic templates are supported only in C++11. The answer from pixelpoint show a similar technique using older programming styles.
It's weird that C++ does not have such a thing out of the box. They recently added to_string(), which in my opinion is a great step forward. I'm wondering if they will add a .format
operator to the std::string
eventually...
As alexk7 pointed out, A +1
is needed on the return value of std::snprintf
, since we need to have space for the \0
byte. Intuitively, on most architectures missing the +1
will cause the required
integer to be partially overwritten with a 0
. This will happen after the evaluation of required
as actual parameter for std::snprintf
, so the effect should not be visible.
This problem could however change, for instance with compiler optimization: what if the compiler decides to use a register for the required
variable? This is the kind of errors which sometimes result in security issues.