6

我正在用 Microsoft Visual C++ 编写,我希望我的程序可以从标准输入或使用istream_iterator. 谷歌搜索互联网并没有显示我认为它必须多么简单。例如,我可以很容易地编写它并从标准输入中读取:

#include <iostream>
#include <string>
#include <iterator>

using namespace std;

int main()
{
   istream_iterator<string> my_it(cin);
   for (; my_it != istream_iterator<string>(); my_it++)
      printf("%s\n", (*my_it).c_str());
}

或者我可以写这个并从文件中读取:

#include <iostream>
#include <string>
#include <iterator>
#include <fstream>

using namespace std;

int main(int argc, char** argv)
{
   ifstream file(argv[1]);
   istream_iterator<string> my_it(file);
   for (; my_it != istream_iterator<string>(); my_it++)
      printf("%s\n", (*my_it).c_str());
}

但是我如何将这两者结合起来,以便一个简单的(argc == 2)检查让我用文件流或标准输入初始化我的输入流迭代器并继续我的快乐方式?

4

4 回答 4

14

您可以在构造迭代器后分配它:

int main(int argc, char** argv)
{
   ifstream file;
   istream_iterator<string> my_it;

   if(argc == 2) {
      file.open(argv[1]);
      my_it = istream_iterator<string>(file);
   } else {
      my_it = istream_iterator<string>(cin);
   }
}
于 2009-12-16T02:26:09.527 回答
1

乍一看,最简单的解决方案是?:像这样使用三元运算符:

istream_iterator<string> my_it( (argc == 2) ? ifstream(argv[1]) : cin );

但是,这不太行得通,因为它构造了一个临时ifstream对象,该对象将在语句结束时被销毁。因此,您需要一种有条件地创建,并在循环ifstream后有条件地销毁它的方法。符合要求。因此:forstd::auto_ptr<>

auto_ptr<ifstream> file((argc == 2) ? new ifstream(argv[1]) : NULL);
istream_iterator<string> my_it( (argc == 2) : *file : cin);
for (; my_it != istream_iterator<string>(); my_it++)
   printf("%s\n", (*my_it).c_str());

一个不同的,可能更清洁的解决方案是将迭代移动到一个单独的函数,该函数采用istream&.

我之前在网上看到过这个问题,由一位 C++ 大师介绍过。不幸的是,我不记得确切的地点,或由谁!我想是在 DDJ 上,也许是 Sutter 或 Alexandrescu?

于 2009-12-16T02:29:05.340 回答
1

这个小片段将为您提供一个 istream input,它可以是文件或 std::cin。

std::ifstream filestream;
if ( use_file )
    filestream.open( ... );
std::istream &input = use_file ? filestream : std::cin;

您现在可以使用input而不必担心输入来自哪个来源。

于 2009-12-16T02:25:01.037 回答
0

你的意思是这样的:(使用指针)

#include <iostream>
#include <string>
#include <iterator>
#include <fstream>

using namespace std;

int main(int argc, char** argv)
{
   istream_iterator<string>* my_it = NULL;
   if (argc == 2)
   {
       ifstream file(argv[1]);
       my_it = new istream_iterator<string>(file);
   }
   else
   {
       my_it = new istream_iterator<string>(cin);
   }

   ...

   delete my_it;
}

不过,我还没有测试过。那是你所追求的吗?

于 2009-12-16T02:25:15.653 回答