Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
0 / 0 / 0
Регистрация: 05.11.2015
Сообщений: 33

Задача с чтением из потока итератором

10.04.2019, 02:12. Показов 1297. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Делаю задачу из книги Липмана, есть входная последовательность чисел через istream_iterator и 2 выходные через ostream_iterator.
Вот код:
C++
1
2
3
4
5
6
7
8
9
ifstream ifs("txt");
ofstream out1("out1"), out2("out2");
istream_iterator<int> is_iter(ifs), eof;
ostream_iterator<int> os_iter1(out1, "\n");
ostream_iterator<int> os_iter2(out2, "\n");
 
auto iter = is_iter;
copy_if(is_iter, eof, os_iter1, [](const int a) { return (a % 2); });
copy_if(iter, eof, os_iter2, [](const int a) { return !(a % 2); });
Почему-то 1 последовательность нормально записывает нечетные числа, перебирая все значения, а 2 последовательность выводит только первое значение из списка.
Причем проблема, как я понял, в потоковом итераторе istream_iterator<int>, т.к. когда вместо него подавался вектор - все работало как надо.
В связи с чем 2 раз функция copy_if() не отрабатывает как надо?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
10.04.2019, 02:12
Ответы с готовыми решениями:

Задача "Медиафайлы" с чтением из файла
Пожалуйста, помогите решить задачу. Точнее упростить код. Имя файла, содержащего исходные данные: media.dat Имя выходного файла:...

Работа с итератором
Есть задание: Описать функцию с двумя параметрами: контейнер-список целых элементов и контейнер-вектор указателей на целые. Функция...

Проблема с итератором
Добрый день! На днях столкнулся с трудностью. Есть текстовый файл с ионами. Моя функция должна перебрать этот файл и выбрать оттуда...

11
 Аватар для igorrr37
2882 / 2029 / 992
Регистрация: 21.12.2010
Сообщений: 3,782
Записей в блоге: 9
10.04.2019, 06:55
C++
1
2
3
4
std::copy_if(is_iter, eof, os_iter1, [](const int a) { return (a % 2); });
ifs.clear();
ifs.seekg(0, std::ios::beg);
std::copy_if(iter, eof, os_iter2, [](const int a) { return !(a % 2); });
1
0 / 0 / 0
Регистрация: 05.11.2015
Сообщений: 33
10.04.2019, 15:41  [ТС]
А почему так получается? Ведь вроде 1 итератор iter должен изменять свой указатель на текущий объект и увеличиваться, пока не дойдет до eof, как и происходит в случае работы с последовательными контейтерами. Почему в случае с потоком итератор сохраняет свое состояние, а поток, из которого происходило чтение меняется?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
10.04.2019, 15:47
Цитата Сообщение от dexterov Посмотреть сообщение
Почему в случае с потоком итератор сохраняет свое состояние
какой итератор сохраняет состояние?
0
0 / 0 / 0
Регистрация: 05.11.2015
Сообщений: 33
10.04.2019, 15:57  [ТС]
Итератор iter, мы ведь его предварительно сохранили строчкой выше.
C++
1
2
3
auto iter = is_iter;
copy_if(is_iter, eof, os_iter1, [](const int a) { return (a % 2); });
copy_if(iter, eof, os_iter2, [](const int a) { return !(a % 2); });
Хотя как я понял, и итератор is_iter тоже как указывал на начало, так и указывает. Т.к. без операций clear() и seekg() вторая функция copy_if() выводит в файл только 1-й элемент из потока ifs, не обрабатывая дальше.

Добавлено через 4 минуты
Чтобы было понятнее, о чем я говорю - и без объявления новой переменной iter код работает аналогично первоначальному варианту (аналогично не правильно):
C++
1
2
copy_if(is_iter, eof, os_iter1, [](const int a) { return (a % 2); });
copy_if(is_iter, eof, os_iter2, [](const int a) { return !(a % 2); });
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
10.04.2019, 16:05
dexterov, iter и is_iter это два разных итератора, установленных, на первый элемент последовательности. Первая функция copy_if устанавливает is_iter на конец последовательности, а поток в состояние EOF, вторая функция вполне успешно разименовывает итератор iter, но дальнейшая попытка его инкрементации, устанавливает его на конец(т.к. поток в состоянии EOF).

Добавлено через 2 минуты
Цитата Сообщение от dexterov Посмотреть сообщение
и без объявления новой переменной iter код работает аналогично первоначальному варианту
это потому что итераторы передаются по значению(копируются), т.к оптимизированы под это.
1
0 / 0 / 0
Регистрация: 05.11.2015
Сообщений: 33
10.04.2019, 16:16  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
dexterov, iter и is_iter это два разных итератора, установленных, на первый элемент последовательности. Первая функция copy_if устанавливает is_iter на конец последовательности, а поток в состояние EOF, вторая функция вполне успешно разименовывает итератор iter, но дальнейшая попытка его инкрементации, устанавливает его на конец(т.к. поток в состоянии EOF).

Добавлено через 2 минуты

это потому что итераторы передаются по значению(копируются), т.к оптимизированы под это.
Не понимаю, почему вы говорите, что первая функция copy_if() устанавливает is_iter на конец последовательности. Вот аналогичный код для вектора:
C++
1
2
3
4
5
6
7
8
9
    
vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
ofstream out1("out1"), out2("out2");
ostream_iterator<int> os_iter1(out1, "\n");
ostream_iterator<int> os_iter2(out2, "\n");
 
auto iter = v.begin();
copy_if(iter, v.end(), os_iter1, [](const int a) { return (a % 2); });
copy_if(iter, v.end(), os_iter2, [](const int a) { return !(a % 2); });
В данном случае один и тот же итератор iter сначала пробегается по вектору в 1-й функции copy_if(), но при работе со 2-й функцией он опять пробегается по всему вектору(т.е. получается, он опять ссылался на v.begin()?)

Насколько я понял, при работе с потом ifstream все дело в том, что потом изменяет свое состояние на EOF после первого прохода?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
10.04.2019, 16:21
Цитата Сообщение от dexterov Посмотреть сообщение
Не понимаю, почему вы говорите, что первая функция copy_if() устанавливает is_iter на конец последовательности.
его копию
1
0 / 0 / 0
Регистрация: 05.11.2015
Сообщений: 33
10.04.2019, 16:31  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
его копию
Да, теперь понятно, почему переменная, хранящая итератор, не изменяется после 1-й функции copy_if().
Понятно и по состоянию потока, но не ясно, зачем нужно seekg()? Ведь мы сбрасываем состояние потока в исходное состояние (его состояние было EOF становится не EOF), итератор указывает на начало этого потока и нужное нам начальное число, но без задания указания
C++
1
ifs.seekg(0, ios::beg);
работать не будет, почему?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
10.04.2019, 16:47
Цитата Сообщение от dexterov Посмотреть сообщение
состояние было EOF становится не EOF
состояние потока не ограничивается только лишь флагами состояний, среди прочего есть позиция "курсора" для чтения, большинство операций с итераторами потоков синхронизируется с этими данными(т.е. для ++iter нужно знать, что читаем дальше)

Добавлено через 10 минут
dexterov, вообще, возьмите за правило инициализировать итератор перед самым его использованием, не раньше, т.к. любые изменения контейнера после инициализации могут сделать итератор невалидным, а значит привести к ошибкам
1
0 / 0 / 0
Регистрация: 05.11.2015
Сообщений: 33
10.04.2019, 16:58  [ТС]
Цитата Сообщение от zayats80888 Посмотреть сообщение
состояние потока не ограничивается только лишь флагами состояний, среди прочего есть позиция "курсора" для чтения, большинство операций с итераторами потоков синхронизируется с этими данными(т.е. для ++iter нужно знать, что читаем дальше)
Не понятно, про курсор чтения. Например, есть в потоке 5 чисел: 1, 2, 3, 4, 5. Состояние потока - не EOF, итератор указывает на начало потока, т.е. на число 1. На каждой итерации он должен инкрементировать указатель, но вместо числа 2 будет сразу ссылаться на конец потока. Получается, есть 2 сущности: итератор и внутренний указатель в потоке? И итератор ориентируется именно на этот указатель потока?
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
10.04.2019, 17:13
Цитата Сообщение от dexterov Посмотреть сообщение
И итератор ориентируется именно на этот указатель потока?
типа того. Вообще у потока нет собственного итератора, однако библиотека iterator предлагает такую специализацию, вот кусок начинки для istream_iterator:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//...
istream_iterator(istream_type& _Istr)
    : _Myistr(_STD addressof(_Istr))
{   // construct with input stream
    _Getval();
}
 
_NODISCARD const _Ty& operator*() const
{   // return designated value
    return (_Myval);
}
 
_NODISCARD const _Ty * operator->() const
{   // return pointer to class object
    return (_STD addressof(_Myval));
}
 
istream_iterator& operator++()
{   // preincrement
    _Getval();
    return (*this);
}
//...
void _Getval()
{   // get a _Ty value if possible
    if (_Myistr != nullptr && !(*_Myistr >> _Myval))
    {
        _Myistr = nullptr;
    }
}
//...
как видите чтение из потока происходит при инициализации или инкрементации и т.д, но не при разыменовании
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.04.2019, 17:13
Помогаю со студенческими работами здесь

ошибка с итератором
Помогите, пожалуйста, не могу понять зачем вычитать нужно еденицу из deq1.begin() #include &lt;iostream&gt; #include &lt;string&gt; ...

Проблема с итератором в <vector>
Всем привет. Помогите пожалуйста решить проблему: У меня существует класс class Book { string author,title,publishing; int...

Сравнение указателя с итератором
Здравствуйте, уважаемые знатоки! Продолжая изучать STL и итераторы наткнулся на такую вот аналогию: #include &lt;iostream&gt; ...

Вывод коллекции итератором не работает
Есть два способа вывода коллекции в консоль: for (Integer i:arrayList) //итератором System.out.println(i); ...

Класс-контейнер стек с итератором
У меня есть задание - калькулятор комплексных чисел. Нужна помощь в написании класса-контейнера(стека), который должен хранить комплексные...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru