31

When I put something into a stringstream, let's say a real number, if I then insert that stringstream object into cout...what am I looking at?

Usually I'm getting some strange number. Is this a memory location? Just curious.

It looks like the below comment hit it but here's what I'm trying to do:

string stringIn; 
stringstream holdBuff;
holdBuff << getline(cin, stringIn);
cout << holdBuff; 

Basically I was just trying to see what holdBuff looked like once I inserted stringIn. I am trying to have the user enter a string and then I want to step through it looking for it's contents and possilbly converting...

MCP
  • 4,436
  • 12
  • 44
  • 53

4 Answers4

29

Yes, you are likely to see the address of the stringstream.

If you want to display the string it contains, try

cout << stream.str();
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • 1
    this creates a copy of the buffer since str() returns by value. – David Feurle Jan 11 '12 at 17:50
  • 1
    @DavidFeurle Any way to not copy it, but get the address of the underlying buffer used by the stringstream? – TamaMcGlinn Jun 26 '20 at 10:02
  • 1
    @TamaMcGlinn you could use the function rdbuf to access the underlying buffer. You stream the rdbuf directly to another stream without copying. But you can not get an pointer to the inner buffer since the rdbuf does not need to be implemented that way. However you could implement your own rdbuf which allows access to the inner buffer. – David Feurle Jun 26 '20 at 10:46
28

What do you think

holdBuff << getline(cin, stringIn);

is doing. The return type of getline is a reference to the stream being read (cin) in this case. Since there's no << defined which takes an std::istream as second argument, the compiler tries different conversions: in C++11, std::istream has an implicit conversion to bool, and in earlier C++, an implicit conversion to std::ios*, or something similar (but the only valid use of the returned value is to convert it to bool). So you'll either output 1 (C++11), or some random address (in practice, usually the address of the stream, but this is not guaranteed). If you want to get the results of a call to getline into an std::ostringstream, you need two operations (with a check for errors between them):

if ( !getline( std::cin, stringIn ) )
    //  Error handling here...
holdBuff << stringIn;

Similarly, to write the contents of a std::ostringstream,

std::cout << holdBuf.str() ;

is the correct solution. If you insist on using an std::stringstream when an std::ostringstream would be more appropriate, you can also do:

std::cout << holdBuf.rdbuf();

The first solution is preferable, however, as it is far more idiomatic.

In any case, once again, there is no << operator that takes any iostream type, so you end up with the results of the implicit conversion to bool or a pointer.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • Thanks a lot James. Great info. I'll have to look up the difference between ostringstream vs. stringstream. Is that the good/entry level way to pull in a line of possibly mixed types? Thanks. – MCP Jan 12 '12 at 07:46
6
cout << s.rdbuf();

is what you want. Alternatively you may want to

cout << s.str();

which may be more expensive in terms of resources though.

OznOg
  • 4,440
  • 2
  • 26
  • 35
Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
6

Yes it is most likely a memory location of some form or other. Most likely it is the pointer to the stringstream object itself.

You could confirm this as follows:

std::stringstream ss;
unsigned long long ll = (unsigned long long)&ss;
cout << ll;

That said when you want to cout a stringstream you should use the str() function as follows:

cout << ss.str();
Goz
  • 61,365
  • 24
  • 124
  • 204