std::ostringstream bizarre behaviour. Please help!

S

Simon Pryor

I am having some strange problems using std::eek:stringstream.

The simple stuff works okay, but trying to use:
std::eek:stringstream::str(const std::string&)
or:
std::eek:stringstream::eek:stringstream(const std::string&)

Gives some weird results on both Solaris & Linux.

Either that or I'm missing something. I've made a simple program to
demonstrate the problem:

-------------cut-as-ostringstreambug.cc---------------------------
#include <string>
#include <iostream>
#include <sstream>
int main(void)
{
int rc = 0;
std::eek:stringstream oss1;
oss1 << "foo";
oss1.str(std::string());
if (oss1.str() != std::string(""))
{ ++rc; std::cout << __LINE__ << ": Got \""
<< oss1.str() << '\"' << std::endl; }
std::eek:stringstream oss2(std::string("foo"));
oss2 << "bar";
if (oss2.str() != std::string("foobar"))
{ ++rc; std::cout << __LINE__ << ": Got \""
<< oss2.str() << '\"' << std::endl; }
std::eek:stringstream oss3;
oss3 << "foo";
oss3.str(std::string("bar"));
oss3 << "foo";
if (oss3.str() != std::string("barfoo"))
{ ++rc; std::cout << __LINE__ << ": Got \""
<< oss3.str() << '\"' << std::endl; }
return rc;
}
--------------------cut-end----------------------------------------

On Solaris:
CC -V
CC: WorkShop Compilers 5.0 98/12/15 C++ 5.0
CC -o ostringstreambug ostringstreambug.cc
ostringstreambug;echo $?
11: Got ""
16: Got "bar"
23: Got "foo"
3

On Linux:
g++ -v
gcc version 3.2.2
g++ -o ostringstreambug ostringstreambug.cc
ostringstreambug;echo $?
16: Got "bar"
23: Got "foo"
2

Now, I would expect to see no output and a return value of 0 on all
machines.

The only thing I can think of is that there is some sort of "freezing" the
way there was with the old "char* ostrstream::str()" stuff, but I don't
find anything that documents the intended behaviour.

Can anyone help?????????? please????

--

+------------------------------------------------------------------
| Simon Pryor, mailto:[email protected]
| Alcatel Bell Space N.V.
| Berkenrodelei 33, phone: +32 3 829 5130
| B-2660 Hoboken, Belgium. fax: +32 3 829 5502
+------------------------------------------------------------------
 
P

Peter Kragh

Simon said:
#include <string>
#include <iostream>
#include <sstream>
int main(void)
{
int rc = 0;
std::eek:stringstream oss1;
oss1 << "foo";
oss1.str(std::string());
if (oss1.str() != std::string(""))
{ ++rc; std::cout << __LINE__ << ": Got \""
<< oss1.str() << '\"' << std::endl; }
std::eek:stringstream oss2(std::string("foo"));

Try this:

std::eek:stringstream oss2(std::string("foo"), std::ios_base::eek:ut |
std::ios_base::app);
oss2 << "bar";
if (oss2.str() != std::string("foobar"))
{ ++rc; std::cout << __LINE__ << ": Got \""
<< oss2.str() << '\"' << std::endl; }
std::eek:stringstream oss3;

Try:

std::eek:stringstream oss3(std::ios_base::eek:ut | std::ios_base::app);

oss3 << "foo";
oss3.str(std::string("bar"));
oss3 << "foo";
if (oss3.str() != std::string("barfoo"))
{ ++rc; std::cout << __LINE__ << ": Got \""
<< oss3.str() << '\"' << std::endl; }
return rc;
}
--------------------cut-end----------------------------------------

On Solaris:
CC -V
CC: WorkShop Compilers 5.0 98/12/15 C++ 5.0
CC -o ostringstreambug ostringstreambug.cc
ostringstreambug;echo $?
11: Got ""
16: Got "bar"
23: Got "foo"
3

On Linux:
g++ -v
gcc version 3.2.2
g++ -o ostringstreambug ostringstreambug.cc
ostringstreambug;echo $?
16: Got "bar"
23: Got "foo"
2

Now, I would expect to see no output and a return value of 0 on all
machines.

The only thing I can think of is that there is some sort of "freezing" the
way there was with the old "char* ostrstream::str()" stuff, but I don't
find anything that documents the intended behaviour.

Can anyone help?????????? please????

According to

http://www.roguewave.com/support/docs/sourcepro/stdlibref/basic-stringbuf.html#idx403

, you need to use out | app for the rdbuf. Otherwise the output sequence
points to the first character in the buffer.

I tried this on gcc version 3.3.1 and it worked. However, I also tried
with Microsoft's C++ compiler version 13.10.3052 and it didn't work
(maybe I should update it :) ).

HTH.

BR,
Peter
 
S

Simon Pryor

Thanks for your help!

This fully fixed it for Linux and partially fixed it for Solaris.

However, when resetting to a NULL string, on Solaris, there was still a
problem (If you refer to my original posting, you can see there was already
a difference in output between Solaris & Linux.
Running Purify on Solaris also gave all sorts of FMR & UMR errors, with this:

std::eek:stringstream oss1(std::ios_base::eek:ut | std::ios_base::app);
oss1 << "foo";
oss1.str(std::string()); // or oss1.str("");
if (oss1.str().size())
{ ++rc; std::cout << __LINE__ << ": Got "
<< oss1.str().size() << "/" << int(oss1.str().data()[0])
<< std::endl; }

On Solaris, I get:

11: Got 1/0
1

So there is an internal bug in the Solaris STD library of C++ 5.0!

Maybe a workaround is always to "reset" to a space or newline or
something like that, though that's not always possible to guarantee
everyone doing this :-(

--

+------------------------------------------------------------------
| Simon Pryor, mailto:[email protected]
| Alcatel Bell Space N.V.
| Berkenrodelei 33, phone: +32 3 829 5130
| B-2660 Hoboken, Belgium. fax: +32 3 829 5502
+------------------------------------------------------------------
 
M

Moskvichev Nikolay

Peter said:
According to

http://www.roguewave.com/support/docs/sourcepro/stdlibref/basic-stringbuf.html#idx403

, you need to use out | app for the rdbuf. Otherwise the output sequence
points to the first character in the buffer.

I tried this on gcc version 3.3.1 and it worked. However, I also tried
with Microsoft's C++ compiler version 13.10.3052 and it didn't work
(maybe I should update it :) ).
It didn't work on Microsoft C++ compiler version 13.10.3077 and
Borland C++ compiler version 5.6.4 too. (Dinkumware & STLPort IIRC)
 
S

Stephen Howe

Try this:
std::eek:stringstream oss2(std::string("foo"), std::ios_base::eek:ut |
std::ios_base::app);

Unfortunately there is nothing in the standard which indicates ostringstream
takes any notice of flags like std::ios_base::app. So implementations are
free to ignore them in constructors

Stephen
 
P

Peter Kragh

Stephen said:
Unfortunately there is nothing in the standard which indicates ostringstream
takes any notice of flags like std::ios_base::app. So implementations are
free to ignore them in constructors

Maybe, I misunderstood chapter 27.7.3.1 (which I should have refered to
in the first place) then:

<quote>
Constructs an object of class basic_ostringstream, initializing the base
class with basic_ostream(& sb) and initializing sb with
basic_stringbuf<charT,traits,Allocator>( which | ios_base::eek:ut))
</quote>

Please correct me, if I'm wrong.

- Peter
 

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,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top