У меня есть следующий код:
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
Я хочу, чтобы каждая строка была новым элементом в моем векторе, любая идея, как решить эту проблему?
Похоже, есть пример в переполнении стека уже в разделе Как перебирать строку 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));
"Отказ от ответственности: я не пробовал это сам, я просто доверяю Джерри Коффину, основанному на его репутации и т.д.
Вы можете создать свой собственный линейный итератор:
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));
Вместо использования istream_iterator лучше всего использовать функцию istream :: getline.
Кажется, нет другого способа, кроме использования std :: getline и того же цикла while.