I have to format std::string
with sprintf
and send it into file stream. How can I do this?
相关问题
- Sorting 3 numbers without branching [closed]
- How to compile C++ code in GDB?
- Why does const allow implicit conversion of refere
- how to split a list into a given number of sub-lis
- thread_local variables initialization
相关文章
- JSP String formatting Truncate
- Class layout in C++: Why are members sometimes ord
- How to mock methods return object with deleted cop
- Which is the best way to multiply a large and spar
- C++ default constructor does not initialize pointe
- Selecting only the first few characters in a strin
- What exactly do pointers store? (C++)
- Converting glm::lookat matrix to quaternion and ba
In order to format
std::string
in a 'sprintf' manner, callsnprintf
(argumentsnullptr
and0
) to get length of buffer needed. Write your function using C++11 variadic template like this:Compile with C++11 support, for example in GCC:
g++ -std=c++11
Usage:
This is how google does it:
StringPrintf
(BSD License)and facebook does it in a quite similar fashion:
StringPrintf
(Apache License)Both provide with a convenient
StringAppendF
too.My two cents on this very popular question.
To quote the manpage of
printf
-like functions:In other words, a sane C++11 implementation should be the following:
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 thestd::string
eventually...Edit
As alexk7 pointed out, A
+1
is needed on the return value ofstd::snprintf
, since we need to have space for the\0
byte. Intuitively, on most architectures missing the+1
will cause therequired
integer to be partially overwritten with a0
. This will happen after the evaluation ofrequired
as actual parameter forstd::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.Took the idea from Dacav and pixelpoint's answer. I played around a bit and got this:
With sane programming practice I believe the code should be enough, however I'm still open to more secure alternatives that are still simple enough and would not require C++11.
And here's another version that makes use of an initial buffer to prevent second call to
vsnprintf()
when initial buffer is already enough.(It turns out that this version is just similar to Piti Ongmongkolkul's answer, only that it doesn't use
new
anddelete[]
, and also specifies a size when creatingstd::string
.The idea here of not using
new
anddelete[]
is to imply usage of the stack over the heap since it doesn't need to call allocation and deallocation functions, however if not properly used, it could be dangerous to buffer overflows in some (perhaps old, or perhaps just vulnerable) systems. If this is a concern, I highly suggest usingnew
anddelete[]
instead. Note that the only concern here is about the allocations asvsnprintf()
is already called with limits, so specifying a limit based on the size allocated on the second buffer would also prevent those.)string doesn't have what you need, but std::stringstream does. Use a stringstream to create the string and then extract the string. Here is a comprehensive list on the things you can do. For example:
will give you 10 decimal places of precision when printing a double or float.
This is the code I use to do this in my program... It's nothing fancy, but it does the trick... Note, you will have to adjust your size as applicable. MAX_BUFFER for me is 1024.