C++ equivalent of StringBuffer/StringBuilder?
NOTE this answer has received some attention recently. I am not advocating this as a solution (it is a solution I have seen in the past, before the STL). It is an interesting approach and should only be applied over std::string
or std::stringstream
if after profiling your code you discover this makes an improvement.
I normally use either std::string
or std::stringstream
. I have never had any problems with these. I would normally reserve some room first if I know the rough size of the string in advance.
I have seen other people make their own optimized string builder in the distant past.
class StringBuilder {
private:
std::string main;
std::string scratch;
const std::string::size_type ScratchSize = 1024; // or some other arbitrary number
public:
StringBuilder & append(const std::string & str) {
scratch.append(str);
if (scratch.size() > ScratchSize) {
main.append(scratch);
scratch.resize(0);
}
return *this;
}
const std::string & str() {
if (scratch.size() > 0) {
main.append(scratch);
scratch.resize(0);
}
return main;
}
};
It uses two strings one for the majority of the string and the other as a scratch area for concatenating short strings. It optimise's appends by batching the short append operations in one small string then appending this to the main string, thus reducing the number of reallocations required on the main string as it gets larger.
I have not required this trick with std::string
or std::stringstream
. I think it was used with a third party string library before std::string, it was that long ago. If you adopt a strategy like this profile your application first.
The C++ way would be to use std::stringstream or just plain string concatenations. C++ strings are mutable so the performance considerations of concatenation are less of a concern.
with regards to formatting, you can do all the same formatting on a stream, but in a different way, similar to cout
. or you can use a strongly typed functor which encapsulates this and provides a String.Format like interface e.g. boost::format
std::string
is the C++ equivalent: It's mutable.
The std::string.append
function isn't a good option because it doesn't accept many forms of data. A more useful alternative is to use std::stringstream
; like so:
#include <sstream>
// ...
std::stringstream ss;
//put arbitrary formatted data into the stream
ss << 4.5 << ", " << 4 << " whatever";
//convert the stream buffer into a string
std::string str = ss.str();