代码之家  ›  专栏  ›  技术社区  ›  GrantJ

使用IStream_迭代器并从标准输入或文件中读取

  •  6
  • GrantJ  · 技术社区  · 15 年前

    我在微软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) 检查允许我用文件流或stdin初始化输入流迭代器,然后继续我的快乐之路?

    4 回复  |  直到 10 年前
        1
  •  11
  •   Commodore Jaeger    15 年前

    构造迭代器后,可以将其分配给它:

    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);
       }
    }
    
        2
  •  1
  •   Ben Karel    15 年前

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

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

    但是,这并不是很有效,因为它构造了一个临时的 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?

        3
  •  1
  •   Drew Dormann    15 年前

    这个小片段会给你一个IStream input 可以是文件,也可以是std::cin。

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

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

        4
  •  0
  •   Smashery    15 年前

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

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

    不过,我还没有测试过这个。这就是你想要的吗?