Прочитать содержимое файла и сохранить его в векторе, используя std :: copy

0

У меня есть следующий код:

    std::istream_iterator<std::string> eos;              
    std::istream_iterator<std::string> iit (File);
    std::vector<std::string> result;
    std::copy(iit,eos,std::back_inserter(result));
    for(auto it=result.begin(); it!=result.end(); ++it )
        std::cout << *it << std::endl;

Я использую итераторы для чтения содержимого File и сохранить результат на мой вектор, я не хочу, чтобы использовать любое while или for цикла, я хочу, чтобы это сделать, используя только любую STL функцию, поэтому я попытался copy. Содержимое файла находится в следующем виде:

Pork bone:4
Pigs trotters:4
Loin of pork:4

Проблема в том, что предыдущий код читает каждую строку до пробела или нового символа строки, поэтому мой вектор выглядит так:

Pork
bone:4
Pigs
trotters:4
Loin
of
pork:4

Я хочу, чтобы каждая строка была новым элементом в моем векторе, любая идея, как решить эту проблему?

Теги:
stl

4 ответа

2
Лучший ответ

Похоже, есть пример в переполнении стека уже в разделе Как перебирать строку cin по строке в C++?

Цитирование соответствующего бита:

class line {
    std::string data;
public:
    friend std::istream &operator>>(std::istream &is, line &l) {
        std::getline(is, l.data);
        return is;
    }
    operator std::string() const { return data; }    
};

Например, чтобы прочитать все строки в файле в вектор строк, вы можете использовать что-то вроде:

std::vector<std::string> lines;

std::copy(std::istream_iterator<line>(std::cin), 
          std::istream_iterator<line>(),
          std::back_inserter(lines));

"Отказ от ответственности: я не пробовал это сам, я просто доверяю Джерри Коффину, основанному на его репутации и т.д.

1

Вы можете создать свой собственный линейный итератор:

template<typename T>
class line_iterator
    : public std::iterator<std::input_iterator_tag, T>
{
public:
    typedef std::istream istream_type;
    typedef T value_type;

    line_iterator(istream_type& is) : ptr(&is) { getInput(); }
    line_iterator() : ptr(nullptr) { }

    T const& operator*() const
    {
        return value;
    }

    line_iterator& operator++()
    {
        getInput();
        return *this;
    }

    T* operator->()
    {
        return &value;
    }

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

    friend bool operator==(const line_iterator& lhs, const line_iterator& rhs)
    {
        return lhs.ptr == rhs.ptr;
    }

    friend bool operator!=(const line_iterator& lhs, const line_iterator& rhs)
    {
        return !(lhs == rhs);
    }
private:
    T value;
    istream_type* ptr;

    void getInput()
    {
        if (ptr)
        {
            if (!std::getline(*ptr, value)) ptr = nullptr;
        }
    }
};

Теперь вы можете просто сделать:

std::copy(line_iterator<std::string>(File),
          line_iterator<std::string>(), std::back_inserter(result));
0

Вместо использования istream_iterator лучше всего использовать функцию istream :: getline.

getline vs istream_iterator

http://www.cplusplus.com/reference/istream/istream/getline/

0

Кажется, нет другого способа, кроме использования std :: getline и того же цикла while.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню