ostringstream, ends: what am I missing

J

jay

I was told that an ostringstream should be terminated by ends.

However, the following code snippet does not do what I would expect if
that were the case:

#include <iostream>
#include <sstream>

using namespace std;

int main()
{
ostringstream oss;
string myString;
long aCounter = 0;

oss << ++aCounter << ends;
myString = oss.str() + "_SUFFIX";

cout << myString << endl; // output: "1 _SUFFIX", unexpected

oss.str("");

oss << ++aCounter;
myString = oss.str() + "_SUFFIX";

cout << myString << endl; // output: "2_SUFFIX", wanted

}

So, my question is basically: what is the purpose of ends ?

-j-
 
R

Ron Natalie

jay said:
I was told that an ostringstream should be terminated by ends.

You were told wrong.
So, my question is basically: what is the purpose of ends ?

ends writes a nul byte ('\0') to the stream. Why does it exist and how did
this confusion
come to play? Well heart of the matter is not stringstream, but the
deprecated strstream
classes. These classes, rather than using a std::string to accumulate the
data, use a rather
trickily managed char array. The result, rather than behaving nicely like
a std::string with
a definite length and arbitrary internal contents, fall in to the age-old C
"use a char*" to
fudge a string type. The null byte is required to flag the end of the
C-style string, so putting
it there (either by explicitly writing '\0' or ends) is required. Frankly,
I think it is bogus.
The stream should have placed it itself, just like std::string has to do
when you do c_str()
accesses.

Null bytes are just another character to stringstream and the string class.
If you put one in
the stream or string, it just occupies a position and everything is fine
(until you try to interoperate
with something that cares about nulls, like the old C string functions).

-Ron
 
A

Andy

jay said:
I was told that an ostringstream should be terminated by ends.

However, the following code snippet does not do what I would expect if
that were the case:

#include <iostream>
#include <sstream>

using namespace std;

int main()
{
ostringstream oss;
string myString;
long aCounter = 0;

oss << ++aCounter << ends;
myString = oss.str() + "_SUFFIX";

cout << myString << endl; // output: "1 _SUFFIX", unexpected

oss.str("");

oss << ++aCounter;
myString = oss.str() + "_SUFFIX";

cout << myString << endl; // output: "2_SUFFIX", wanted

}

So, my question is basically: what is the purpose of ends ?

-j-

The above code snippet does indeed do what you are expecting it to do.
I ran the code by copy pasting it in my editor. It did not give
"1_SUFFIX" but just "1". Which compiler are you using? I used Borland
8.5 and g++ (not sure which version).

regards,
andy
 
J

jay

(e-mail address removed) (Andy) wrote in
The above code snippet does indeed do what you are expecting it to do.
I ran the code by copy pasting it in my editor. It did not give
"1_SUFFIX" but just "1". Which compiler are you using? I used Borland
8.5 and g++ (not sure which version).

OK, so it's now clear to me that the ends thing is not necessary at all,
and I have an explanation for some weird behaviour that I have been
experiencing.

I am using MSVC 7.1. Apparently, putting ends at the end of an
ostringstream results in undefined behaviour, is that correct ?

-j-
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top