[英]Redirecting std::cin directly to std::cout
关于标准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
在终端上。
为什么会这样? 为什么这些程序的行为有所不同?
cout << cin
无法按您希望的方式工作 。 在C ++ 11和更高版本中,它甚至不会编译。
您正在看到(现在已过时) “安全布尔”成语的不幸副作用。
在C ++ 11之前, 可以将 std::istream
隐式转换为void*
以模拟布尔语义。 (从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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.