views:

1924

answers:

5

Is there a C++ Standard Template Library class that provides efficient string concatenation functionality, similar to C#'s StringBuilder or Java's StringBuffer?

+1  A: 

You can use .append() for simply concatenating strings.

std::string s = "string1";
s.append("string2");

I think you might even be able to do:

std::string s = "string1";
s += "string2";

As for the formatting operations of C#'s StringBuilder, I believe snprintf (or sprintf if you want to risk writing buggy code ;-) ) into a character array and convert back to a string is about the only option.

Andy Shellam
No, streams are meant for formatting.
Matthieu M.
Not in the same way as printf or .NET's String.Format though, are they?
Andy Shellam
its a little disingenuous to say they are the only way though
jk
@jk - they're the only way when comparing the formatting ability of .NET's StringBuilder, which is what the original question specifically asked. I did say "I believe" so I could be wrong, but can you show me a way to get StringBuilder's functionality in C++ without using printf?
Andy Shellam
@Andy Shellam updated my answer to include some alternative formatting options
jk
+16  A: 

The C++ way would be to use std::stringstream or just plain string concats

edit: with regards formatting you can do all the same formating on a stream, but not in the same way. or you can use a stongly typed functor which encapsulates this and provides a String.Format like interface e.g. boost::format

jk
+2  A: 

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::stringbuffer. 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.

iain
If your scratch string never gets bigger than ScratchSize, then str() will always return an empty string. I think you meant to say "if (scratch.size() > 0)" inside the str() method.
A. Levy
yes you are right thanks for that, I've updated the sample.
iain
+1  A: 

std::string is the C++ equivalent: It's mutable.

dan04
A: 

answered is right.

The append methods, return *this. It is as efficiently as StringBuilder in Java

Creation