minor confusion - std::stringstream and operator (>>/<<)

M

ma740988

Consider:

#include <iostream>
#include <sstream>
#include <string>

int main ( ) {
{
double pi = 3.141592653589793238;
std::stringstream a;
a << pi;
double pi2;
a >> pi2;
std::cout << std::boolalpha << ( pi == pi2 ) << '\n';
}
{
std::string str = "Hello world!";
std::stringstream a;
a << str;
std::string str2;
a >> str2;
std::cout << std::boolalpha << ( str == str2 ) << '\n';
}
}


prints:

false
false

Why is that? I relied on operator << and >> to do essentially do the
right thing.
 
A

Alf P. Steinbach

* ma740988:
Consider:

#include <iostream>
#include <sstream>
#include <string>

int main ( ) {
{
double pi = 3.141592653589793238;
std::stringstream a;
a << pi;
double pi2;
a >> pi2;
std::cout << std::boolalpha << ( pi == pi2 ) << '\n';
}
{
std::string str = "Hello world!";
std::stringstream a;
a << str;
std::string str2;
a >> str2;
std::cout << std::boolalpha << ( str == str2 ) << '\n';
}
}


prints:

false
false

Why is that? I relied on operator << and >> to do essentially do the
right thing.

In the PI case it's because you're comparing floating point values
(which are approximations) for equality. Converting a floating point
value to text and then back generally does not yield exactly the same
value. Some libraries for other languages do, however, have "roundtrip"
functionality for such conversions (e.g. .NET has).

In the HULLO WORLD case it's because operator>> reads one token, the
word "Hello", from the stream, which is not "Hello world!".

Instead of operator>>, use std::getline to read one line.
 
S

Sumit Rajan

ma740988 said:
Consider:

#include <iostream>
#include <sstream>
#include <string>

int main ( ) {
{
double pi = 3.141592653589793238;
std::stringstream a;
a << pi;
double pi2;
a >> pi2;
std::cout << std::boolalpha << ( pi == pi2 ) << '\n';
}

See http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.17
{
std::string str = "Hello world!";
std::stringstream a;
a << str;
std::string str2;
a >> str2;
std::cout << std::boolalpha << ( str == str2 ) << '\n';
}
}

str is "Hello world!" and str2 is just "Hello" since the call to >>
gets the first token only.

Regards,
Sumit.
 
B

BobR

ma740988 wrote in message
Consider:

#include <iostream>
#include <sstream>
#include <string>

int main ( ) {
{
double pi = 3.141592653589793238;
std::stringstream a;
a << pi;
double pi2;
a >> pi2;
std::cout << std::boolalpha << ( pi == pi2 ) << '\n';
}
{
std::string str = "Hello world!";
std::stringstream a;
a << str;
std::string str2;
a >> str2;
std::cout << std::boolalpha << ( str == str2 ) << '\n';
}
}


prints:
false
false

Why is that? I relied on operator << and >> to do essentially do the
right thing.

int main(){
{
double pi = 3.141592653589793238;
std::stringstream a;
int OutPre = a.precision();
a.setf(std::ios::fixed);
a.precision(20);
a << pi;
double pi2;
a >> pi2;
std::cout <<pi<<" "<<pi2<<'\n';
int OutPreC = std::cout.precision();
std::cout.setf(std::ios::fixed);
std::cout.precision(20);
std::cout <<pi<<" "<<pi2<<'\n';
std::cout << std::boolalpha << ( pi == pi2 ) << '\n';
a.precision(OutPre);
std::cout.precision(OutPreC);
}
{
std::string str = "Hello world!";
std::stringstream a;
a << str;
std::string str2;
a >> str2;
cout <<str<<" "<<str2<<'\n';
cout << std::boolalpha << ( str == str2 ) << '\n';
}
return 0;
}

// 3.14159 3.14159
// 3.14159265358979310 3.14159265358979310
// true
// Hello world! Hello
// false
 
M

ma740988

BobR said:
int main(){
{
double pi = 3.141592653589793238;
std::stringstream a;
int OutPre = a.precision();
a.setf(std::ios::fixed);
a.precision(20);
a << pi;
double pi2;
a >> pi2;
std::cout <<pi<<" "<<pi2<<'\n';
int OutPreC = std::cout.precision();
std::cout.setf(std::ios::fixed);
std::cout.precision(20);
std::cout <<pi<<" "<<pi2<<'\n';
std::cout << std::boolalpha << ( pi == pi2 ) << '\n';
a.precision(OutPre);
std::cout.precision(OutPreC);
}

Bob, you're use of the precision here is something I need to get my
head around. Nice mix of stringstreams with iostream.

Anyway, thanks for the snippet
 
B

BobR

ma740988 wrote in message ...
Bob, you're use of the precision here is something I need to get my
head around. Nice mix of stringstreams with iostream.

Anyway, thanks for the snippet

Your welcome. However, be aware that it is just a 'workaround', not a real
solution. It works on window$ and GNU/Linux running on the same i86 machine
(using GCC, MinGW). It may not work on other types of CPU/compiler
implementation/non-IEEE formated numbers. You should never use the equality
operator ('==') for type 'double'. Instead, compare the double to a range
unless you are *positive* the double(s) can be represented in binary *on all
machines* likely to run your code. Rounding/truncation can be a bitch! <G>

As for the stream manipulators, experiment to get used to using them. They
were confusing to me in the early days of C++, but, now it's like scratching
an itch, I don't even think about it. <G>
What you see on the CRT(screen) may be different than what is actually in the
computers memory.
 

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