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

Redirecting std::cin directly to std::cout

本文关键字:std 重定向 cout cin      更新时间:2023-10-16

关于标准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;
}

结果是非常不同的。当我运行这段代码时,我得到一个没完没了的

流。

0 x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d300x600d30

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

cout << cin不会按您希望的方式工作。在c++ 11及以后的版本中,它甚至无法编译。

您看到的是(现已废弃)的不幸副作用。"安全bool"习惯用法。

在c++ 11之前,std::istream可以隐式转换为void*来模拟bool语义。(从c++ 11开始,explicit operator bool() const填补了这个角色)

因此,代码:
while (cout << cin)

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

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

cin不处于错误状态时,此强制转换允许产生任何非null void*。在您的示例中,它正在生成指针0x600d30

在第一种解决方案中,您从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;
}