C++ 使用 istream_iterator 并从标准输入或文件中读取
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1911822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using istream_iterator and reading from standard input or file
提问by GrantJ
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:
我正在使用 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());
}
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?
但是我如何将这两者结合起来,以便一个简单的(argc == 2)检查让我用文件流或标准输入初始化我的输入流迭代器,然后继续我的快乐方式?
回答by Commodore Jaeger
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);
}
}
回答by Drew Dormann
This small snippet will give you an istream inputthat can be either a file or std::cin.
这个小片段将为您提供一个 istream input,它可以是文件或 std::cin。
std::ifstream filestream;
if ( use_file )
filestream.open( ... );
std::istream &input = use_file ? filestream : std::cin;
You may now use inputwithout worrying which source the input is coming from.
您现在可以使用input而无需担心输入来自哪个来源。
回答by Ben Karel
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 ifstreamobject, 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 forloop. std::auto_ptr<>fits the bill. Thus:
但是,这不会完全奏效,因为它构造了一个临时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());
A different, probably cleaner solution would be to move the iteration to a separate function that takes istream&.
一个不同的,可能更简洁的解决方案是将迭代移动到一个单独的函数,该函数需要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?
我之前在网上看到过这个问题,由一位 C++ 伟人介绍过。不幸的是,我不记得确切的地点,或由谁!我想是在 DDJ 上,也许是 Sutter 或 Alexandrescu?
回答by Smashery
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?
不过我还没有测试过这个。这就是你所追求的吗?

