使用 istream_iterator 并从标准输入或文件读取

发布于 2024-08-15 04:25:47 字数 902 浏览 4 评论 0原文

我正在使用 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) check 让我可以使用文件流或标准输入初始化输入流迭代器,然后继续我的快乐之路?

I'm writing in Microsoft Visual C++ and I'd like my program to either read from standard input or a file using the istream_iterator. Googling the internets hasn't shown how simple I think it must be. So for example, I can write this pretty easily and read from standard input:

#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());
}

Or I can write this and read from a file:

#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());
}

But how do I combine these two so that a simple (argc == 2) check lets me initialize my input stream iterator with either a file stream or stdin and go on about my merry way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蓝礼 2024-08-22 04:25:47

您可以在构造迭代器后对其进行赋值:

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);
   }
}

You can assign to the iterator after constructing it:

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);
   }
}
柳絮泡泡 2024-08-22 04:25:47

乍一看,最简单的解决方案是使用三元运算符 ?: ,如下所示:

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

但是,这不太有效,因为它构造了一个临时 ifstream 对象,该对象将在声明结束时被销毁。因此,您需要一种有条件地创建 ifstream 并在 for 循环后有条件地销毁它的方法。 std::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?

At first glance, the simplest solution would be to use the ternary operator ?: like this:

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

However, that won't quite work because it constructs a temporary ifstream object, which will be destroyed at the end of the statement. So you need a way of conditionally creating an ifstream, and conditionally destroying it after the for loop. std::auto_ptr<> fits the bill. Thus:

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());

A different, probably cleaner solution would be to move the iteration to a separate function that takes istream&.

I've seen this problem before online, covered by one of the C++ greats. Unfortunately, I don't remember exactly where, or by whom! I think it was on DDJ, maybe Sutter or Alexandrescu?

杯别 2024-08-22 04:25:47

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

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

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

This small snippet will give you an istream input that can be either a file or std::cin.

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

You may now use input without worrying which source the input is coming from.

橙味迷妹 2024-08-22 04:25:47

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

#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;
}

我还没有测试过这个。这就是你所追求的吗?

Do you mean something like this: (using pointers)

#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;
}

I haven't tested this, though. Is that sort of what you're after?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文