将std :: cin直接重定向到std :: cout

时间:2015-08-10 15:55:59

标签: c++ io

关于标准io的练习要求我:

  

从标准输入读取输入并将其写入标准输出。

可能的解决方案是:

#include<iostream>
#include<string>

using std::cin; using std::cout;
using std::string;

int main()
{
    string word;
    while (cin >> word)
        cout << word;

    return 0;
}

在此示例中,字符串充当缓冲区。如果有人试图通过这样做来摆脱缓冲区:

#include<iostream>
using std::cin; using std::cout;

int main()
{
    while (cout << cin)
        ;
    return 0;
}

结果非常不同。当我运行此代码时,我得到一个无休止的

  

0x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d30

在终端上。

为什么会这样?为什么这些程序的行为不同?

2 个答案:

答案 0 :(得分:5)

cout << cin不会按您希望的方式工作。在C ++ 11及更高版本中,它甚至都不会编译。

你看到了(现在过时的)"safe bool" idiom的不幸副作用。

在C ++ 11之前,std::istream could be implicitly converted to a void* to emulate bool semantics.(从C ++ 11开始,explicit operator bool() const填充该角色)

因此,代码:

while (cout << cin)

在C ++ 98或C ++ 03中编译,因为它可以隐式转换为:

while (cout << static_cast<void*>(cin) )

void*未处于错误状态时,允许此强制转换生成任何非NULL cin。在您的情况下,它正在生成指针0x600d30

答案 1 :(得分:1)

在第一个解决方案中,您从cin中提取一个字符串并将其重新注入cout。但是在第二种方式中,编译器尝试将cin转换为适合在cout中注入的值。

您的实现将cin转换为指针并重复打印。我只是简单地将cin转换为bool并重复打印1

但请注意,即使您的第一个版本对多个空格或制表符也不透明,也可能不尊重行。我更喜欢:

#include<iostream>
#include <string>


int main()
{
    std::string line;

    while (std::getline(std::cin, line)) {
        std::cout << line << std::endl;
    }
    return 0;
}