Reputation: 331
An exercise about standard io asks me to:
Read input from the standard input and write it to the standard output.
A possible solution is:
#include<iostream>
#include<string>
using std::cin; using std::cout;
using std::string;
int main()
{
string word;
while (cin >> word)
cout << word;
return 0;
}
The string acts as a buffer in this example. If one tries to get rid of the buffer by doing something like this:
#include<iostream>
using std::cin; using std::cout;
int main()
{
while (cout << cin)
;
return 0;
}
the results are very different. When I run this code I get an interminable stream of
0x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d30
on the terminal.
Why this happens? Why do these programs behave differently?
Upvotes: 3
Views: 1351
Reputation: 63775
cout << cin
will not work the way you want it to. In C++11 and later, it won't even compile.
You are seeing an unfortunate side-effect of the (now obsolete) "safe bool" idiom.
Before C++11, a std::istream
could be implicitly converted to a void*
to emulate bool semantics. (Since C++11, explicit operator bool() const
fills that role)
Therefore, the code:
while (cout << cin)
compiles in C++98 or C++03, because it can be implicitly converted to:
while (cout << static_cast<void*>(cin) )
This cast is allowed to produce any non-NULL void*
when cin
is not in an error state. In your case, it is producing the pointer 0x600d30
.
Upvotes: 6
Reputation: 148910
In first solution, you extract a string from cin and reinject it in cout. But in the second way, compiler tries to convert cin into a value suitable for injection in cout.
Your implementation converted cin to a pointer and repeatedly printed it. Mine simply converted cin to a bool and repeadedly prints 1
.
But beware, even your first version is not transparent to multiple spaces or tabs, and would probably not respect lines either. I would prefer:
#include<iostream>
#include <string>
int main()
{
std::string line;
while (std::getline(std::cin, line)) {
std::cout << line << std::endl;
}
return 0;
}
Upvotes: 1