是否有可以逐行迭代文件的 C 迭代器?

新手上路,请多包涵

我想获得一个 istream_iterator 样式的迭代器,它将文件的每一行作为字符串而不是每个单词返回。这可能吗?

原文由 thehouse 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 527
2 个回答

编辑: 这个技巧已经由其他人 在之前的帖子中 发布过。

很容易拥有 std::istream_iterator 做你想做的事:

 namespace detail
{
    class Line : std::string
    {
        friend std::istream & operator>>(std::istream & is, Line & line)
        {
            return std::getline(is, line);
        }
    };
}

template<class OutIt>
void read_lines(std::istream& is, OutIt dest)
{
    typedef std::istream_iterator<detail::Line> InIt;
    std::copy(InIt(is), InIt(), dest);
}

int main()
{
    std::vector<std::string> v;
    read_lines(std::cin, std::back_inserter(v));

    return 0;
}

原文由 Manuel 发布,翻译遵循 CC BY-SA 3.0 许可协议

也可以使用 基于范围的 for 循环

 // Read from file.
std::ifstream f("test.txt");
for (auto& line : lines(f))
  std::cout << "=> " << line << std::endl;

// Read from string.
std::stringstream s("line1\nline2\nline3\n\n\nline4\n\n\n");
for (auto& line : lines(s))
  std::cout << "=> " << line << std::endl;

其中 lines 定义如下:

 #include <string>
#include <iterator>
#include <istream>

struct line_iterator {
  using iterator_category = std::input_iterator_tag;
  using value_type = std::string;
  using difference_type = std::ptrdiff_t;
  using reference = const value_type&;
  using pointer = const value_type*;

  line_iterator(): input_(nullptr) {}
  line_iterator(std::istream& input): input_(&input) { ++*this; }

  reference operator*() const { return s_; }
  pointer operator->() const { return &**this; }

  line_iterator& operator++() {
    if (!std::getline(*input_, s_)) input_ = nullptr;
    return *this;
  }

  line_iterator operator++(int) {
    auto copy(*this);
    ++*this;
    return copy;
  }

  friend bool operator==(const line_iterator& x, const line_iterator& y) {
    return x.input_ == y.input_;
  }

  friend bool operator!=(const line_iterator& x, const line_iterator& y) {
    return !(x == y);
  }

 private:
  std::istream* input_;
  std::string s_;
};

struct lines {
  lines(std::istream& input): input_(input) {}

  line_iterator begin() const { return line_iterator(input_); }
  line_iterator end() const { return line_iterator(); }

 private:
  std::istream& input_;
};

原文由 dmitriykovalev 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题