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 input
that 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 input
without 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 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:
但是,这不会完全奏效,因为它构造了一个临时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?
不过我还没有测试过这个。这就是你所追求的吗?