【发布时间】:2013-08-06 13:18:31
【问题描述】:
如何判断天气 ostream 是文件还是控制台流。在下面的程序中,我想打印“Hello file!”在写入文件和“你好控制台!”时在写入控制台时。我应该在第 17 行指定什么条件?
#include <fstream>
#include<iostream>
#include <string>
using namespace std;
class A{
public:
A(string msg):_str(msg){}
string str()const {return _str;};
private:
string _str;
};
ostream & operator << (ostream & os, const A & a)
{
if (os is ofstream) //this is line 17
os << "Hello file! " << a.str() << endl;
else
os << "Hello console! " << a.str() << endl;
return os;
}
int main()
{
A a("message");
ofstream ofile("test.txt");
if (!ofile)
cerr << "Unable to open file";
else
ofile << a; // "Hello file"
cout << a << endl; // "Hello console"
}
【问题讨论】:
-
答案当然取决于操作系统。例如,在 UNIX 和类 UNIX 系统中,您可以使用
isatty(2)(其中2是与stderr对应的fd)来检测stderr是否指向终端。我不知道 Windows 等价物是什么。 -
正如 Joe Z 所说,这取决于操作系统,Windows 由于 API 压倒性而更加苛刻。检查this 以了解开始。
-
@JoeZ:即使
stderr指向终端,也不代表operator<<中的流对象指向控制台。它也可以是文件:您也可以在终端程序中打开任何流! -
@Nawaz:同意。您还需要获取与
ofstream关联的fd。如果您将问题重述为“我如何将cout/cerr与其他ofstreams 区分开来?”,那么问题会简单得多,并且对操作系统的依赖程度更低,并且可能足以达到目的。 -
@JoeZ:这可能还不够,因为通常您可能想要检测 bash 重定向(例如,为了避免将颜色控制字符放入文件中)。因此,您实际上确实需要检测
ostream是否指向cout或cerr以及stdout或stderr是TTY 还是文件。当然,为了增加乐趣,如果它是 TTY,您可能需要检查其属性以了解它是否真的支持颜色...