views:

293

answers:

4

could any one tell me about some practical examples on using string streams in c++, i.e. inputing and outputing to a string stream using stream insertion and stream extraction operators?

+8  A: 

You can use string streams to convert anything that implements operator << to a string:

#include <sstream>

template<typename T>
std::string toString(const T& t)
{
  std::ostringstream stream;
  stream << t;

  return stream.str();
}

or even

template <typename U, typename T>
U convert(const T& t)
{
  std::stringstream stream;
  stream << t;

  U u;
  stream >> u;

  return u;
}
Gregory Pakosz
Just remember that this solution will only work for primitive types and overloaded versions of `operator<<` with specific classes.
fogo
@fogo: And since it is relatively common to define streaming operators for classes, that is not such a big deal.
Martin York
@Martin York Indeed, I just considered a proper comment considering the *convert anything* remark in the answer.
fogo
@fogo I edited the answer accordingly
Gregory Pakosz
+1  A: 

Besides advantages there is one point to carefully consider if you use gcc 4.3.1. I didn't checked preceding versions of gcc.

skwllsp
This was an limitation of a specific implementation (gcc). It you follow the link through to the bugzilla bug associated with he problem you will also note that the bug has been marked resolved <qoute>the mutex is not used anymore</quote>
Martin York
Then it is great! I will edit my post in order to add information what this information is relevant only to some versions of gcc.
skwllsp
+2  A: 

They can be used anywhere a normal stream can be used.

So in situations where you were reading from a file you could potentially read from a string stream.

void compile(std::istream& str)
{
    CPlusPlusLexer   lexer(str);
    CPlusPlusParser  parser(lexer);
    BackEnd          backend(parser);

    backend.compile();
}

int main()
{
    std::fstream   file("Plop.cpp");
    compile(file);

    std::stringstream  test("#include <iostream>\n int main() { std::cout << \"H World\n\";}");
    compile(test);
}
Martin York
+2  A: 

I use them mostly as memory buffers, in creating messages:

if(someVector.size() > MAX_SIZE)
{
    ostringstream buffer;
    buffer << "Vector should not have " << someVector.size() << " eleements";
    throw std::runtime_error(buffer.str());
}

or to construct complex strings:

std::string MyObject::GenerateDumpPath()
{
    using namespace std;

    std::ostringstream      dumpPath;

    // add the file name
    dumpPath << "\\myobject."
        << setw(3) << setfill('0') << uniqueFileId
        << "." << boost::lexical_cast<std::string>(state)
        << "_" << ymd.year 
        << "." << setw(2) << setfill('0') << ymd.month.as_number()
        << "." << ymd.day.as_number()
        << "_" << time.hours() 
        << "." << time.minutes() 
        << "." << time.seconds()
        << ".xml";

    return dumpPath.str();
}

It is useful because it brings all the extensibility of std::streams to using character buffers (ostreams extensibility and locales support, buffer memory management is hidden and so on).

Another example I've seen was the error reporting in gsoap library, using dependency injection: soap_stream_fault takes an ostream& parameter to report error messages in.

If you want you can pass it std::cerr, std::cout or an std::ostringstream implementation (I use it with a std::ostringstream implementation).

utnapistim