Jose_mr
Jose_mr

Reputation: 331

Redirecting std::cin directly to std::cout

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

Answers (2)

Drew Dormann
Drew Dormann

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

Serge Ballesta
Serge Ballesta

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

Related Questions