文件和控制台流之间的区别

cpp*_*cpp 9 c++ fstream ostream

如何确定天气ostream是文件或控制台流.在下面的程序中我想打印"Hello file!" 写入文件和"Hello console!"时 在写入控制台时.我应该在第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"
}
Run Code Online (Sandbox Code Playgroud)

小智 4

也许不漂亮,但是

std::streambuf const * coutbuf = std::cout.rdbuf();
std::streambuf const * cerrbuf = std::cerr.rdbuf();

ostream & operator << (ostream & os, const A & a)
{
        std::streambuf const * osbuf = os.rdbuf();

        if ( osbuf == coutbuf || osbuf == cerrbuf )
                os << "Hello console! " << a.str() << endl;
        else
                os << "Hello file! " << a.str() << endl;

        return os;
}
Run Code Online (Sandbox Code Playgroud)

我们可以使用&os == &std::cout,但标准输出可能会重定向到文件,所以我认为最好使用 Streambuf 对象。(请参阅此答案以更好地了解重定向如何工作,以及为什么比较streambuf安全地解决了问题!)

  • @Nawaz“我认为这种方法没有任何问题”:当然,除了它不起作用。例如,如果标准输出已重定向到文件,他仍然会输出“Hello console!”。 (7认同)
  • @Nawaz 不,但这就是重点。否则,您可以只使用全局标志,或传递额外的参数。以这种方式重定向输出是非常非常常见的;比 `std::cout.rdbuf( &amp;aFilebuf );` 更常见。 (3认同)
  • 它仍然不起作用。例如,`myprog &gt; xxx.txt`应该输出`"Hello file!"。(这就是我所说的重定向的意思,而且它非常非常常见。) (2认同)
  • 我认为最初的提问者需要权衡解决方案的通用性。如果他们只想涵盖简单、常见的情况,并且并不真正关心重定向,那么上面的方法看起来是合理的。如果他们需要健壮的东西,那么您需要为您正在使用的任何操作系统开发 API 并编写特定于操作系统的代码。 (2认同)