C++:将cin分配给一个ifstream变量?

18

您知道常用的stdio习语,即使用"-"指定stdin的文件名,例如:

if ((strcmp(fname, "-"))
    fp = fopen(fname);
else
    fp = stdin;

如何使用 ifstream 实例来完成这个任务呢?我收到了一段代码,其中一个类中包含一个 ifstream,我想添加一些代码以完成类似的操作,例如:

if ( filename == "-")
    logstream = cin;  // **how do I do this*?*
else
    logstream.open( filename.c_str() );
2个回答

25

cin不是一个ifstream,但如果可以使用istream代替,那么你就可以获胜。否则,如果你准备好了不考虑可移植性,只需打开/dev/stdin/dev/fd/0等文件即可。 :-)


如果您确实希望程序具有可移植性,并且可以使其使用istream,这里是一种方法:

struct noop {
    void operator()(...) const {}
};

// ...

shared_ptr<istream> input;
if (filename == "-")
    input.reset(&cin, noop());
else
    input.reset(new ifstream(filename.c_str()));

使用noop是为了在cin情况下指定一个什么也不做的删除器,因为cin不应该被删除。


谢谢...这只需要在Linux和OSX上可移植,所以使用/dev/stdin吧!(叹气) - Mark Harrison
1
这说明没有人认真制作过一套像样的C++库。(如果没有那么多版本问题,我会说Boost) - Erik Aronesty
1
顺便说一句,使用C++11,而不是将noop()传递给reset(并定义结构体),一个简单(看起来有趣的)[](...){}就可以实现。 - akim
@akim Yep. Go lambdas! - C. K. Young

0

一个小时前我写了一个非常相似的答案,但在重新阅读问题的这一部分后删除了它:“我收到了一些代码,其中包含一个ifstream作为类的一部分”。问题的标题是误导性的,因为它可能被解读为“如何重定向cin以从文件中读取”,但据我所知,情况恰恰相反:OP已经有了一个ifstream,并希望将其重定向到cin。 - Éric Malenfant
确实如此。我们不能像那样更改ifstream的streambuf。 就像Chris Jester-Young的解决方案一样,需要更改使用的流的确切类型。 - Luc Hermitte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接