Можно ли сделать следующее без использования классических циклов и счётчиков, а с помощью итераторов?
Сначала считать значения из файла обычным оператором <<
(конфигурационные переменные), потом, начиная с текущего места в файле, считать n значений в вектор с помощью итератора на текущий элемент и продвинутого итератора на n элементов. В конце считать остаток в другой вектор.
Как я себе это представляю (в файле строка 1 2 3 4 5
):
#include <iostream>
#include <algorithm>
#include <vector>
#include <fstream>
#include <iterator>
int main() {
std::ifstream file("test.txt");
int first;
file >> first;
std::cout << "First: " << first << '\n';
std::vector<int> next{std::istream_iterator<int>(file), std::next(std::istream_iterator<int>(file), 2)};
std::cout << "Next 2 elements: ";
std::copy(next.begin(), next.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
std::vector<int> rest{std::istream_iterator<int>(file), std::istream_iterator<int>()};
std::cout << "Rest: ";
std::copy(rest.begin(), rest.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
}
Однако вектора оказываются пустыми. Если не использовать вектор next
, то rest
выведется правильно, так что проблема думаю в std::next()
-- он не просто продвигает итератор, но и продвигает файловый указатель. Можно ли как то добиться желаемого?
UPD
Разобрался, почему не работает.
1) "The actual read operation is performed when the iterator is incremented, not when it is dereferenced. The first object is read when the iterator is constructed. Dereferencing only returns a copy of the most recently read object."
2) "Two stream iterators are equal if both of them are end-of-stream iterators or both of them refer to the same stream."
Вариант с сохранением итератора от @AR Hovsepyan также не работает из-за 2), хоть итераторы указывают на правильные элементы.
Можно ли сделать это как-то по-другому?
Используйте std::copy_n
:
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <vector>
int main()
{
{
std::ofstream file{"test.txt"};
file << "1 2 3 4 5";
}
std::ifstream file{"test.txt"};
int first = 0;
file >> first;
std::cout << "First: " << first << '\n';
std::vector<int> next(2);
std::copy_n(std::istream_iterator<int>{file}, 2, next.begin());
std::cout << "Next 2 elements: ";
std::copy(next.begin(), next.end(), std::ostream_iterator<int>{std::cout, " "});
std::cout << '\n';
std::vector<int> rest{std::istream_iterator<int>{file}, {}};
std::cout << "Rest: ";
std::copy(rest.begin(), rest.end(), std::ostream_iterator<int>{std::cout, " "});
std::cout << '\n';
}
Ваш код не работает из за реализаци std::istream_iterator::operator==
:
Checks whether both lhs and rhs are equal. Two stream iterators are equal if both of them are end-of-stream iterators or both of them refer to the same stream.
Два итаратора равны если они оба EOF или оба ссылаются на один поток.
Таким образом следующий код всегда будет выводить true
std::ifstream file{"test.txt"};
std::istream_iterator<int> it{file};
std::cout << std::boolalpha << (it == std::next(it, 2)) << std::endl; //true
и следовательно интервал [it, it + 2) всегда пуст
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Опираясь на это,хочу получить список dll, которые использует каждый процессЯ использую stl list, где каждая нода имеет вот такие поля:
Почему 2 std::istream_iterator считаются одинаковыми, даже если они указывают на разные элементы одного потока? С чем связано такое определение?
есть такой вопрос, хочу сделать UPDATE запрос к базе данных, для этого нужно подготовить запрос, но помимо подстановки данных, я хочу подставить...
есть указатель на массив объектов s и указатель на s