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

Потоковые итераторы - не работает код

04.02.2016, 20:01. Показов 1988. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Выношу на ваш суд следующий код, взятый мной из учебника Лафоре
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
   {
      setlocale( LC_ALL, "rus" );
   list<int> fList(2);               // неинициализированный список
 
   cout << "\nВведите 5 чисел (типа int): ";
                                       // итераторы istream
   istream_iterator<int> cin_iter(cin);   // cin
   istream_iterator<int> end_of_stream;   //eos (конец потока)
                                       // копировать из cin в fList
   copy( cin_iter, end_of_stream, fList.begin() );
 
   cout << endl;                       // вывести fList
   ostream_iterator<int> ositer(cout, "--");
   copy(fList.begin(), fList.end(), ositer);
   cout << endl;
   return 0;
   }
момент первый - это не работает. ввод данных не прекращается после введения пяти символов, что, конечно же, логично, ведь никто не сказал, сколько данных будет внесено. вопрос в том - как это полечить ?

и момент второй, самый главный!
объявляется итератор
C++
1
istream_iterator<int> end_of_stream;
и дальше используется как указатель на конец потока в алгоритме copy.
вопрос - а откуда он узнал что указатель на конец потока ?! его же даже не инициализировали...

заранее спасибо.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
04.02.2016, 20:01
Ответы с готовыми решениями:

Потоковые итераторы
Я новичок, прошел тему &quot;STL&quot; по учебнику Лафоре. Пишу в Code::Blocks, поставить другую IDE возможности мало. При попытке работы с...

Потоковые и обратные итераторы
В MSDN написано:&quot;Существующие контейнеры стандартной библиотеки шаблонов также задают типы reverse_iterator и const_reverse_iterator и...

Потоковые итераторы, конец потока
В одном учебнике по STL есть такой код: std::vector&lt;std::string&gt; vec; ...

33
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
09.02.2016, 20:39
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от zer0mail Посмотреть сообщение
Вспоминается анекдот: "ложки нашлись, но осадочек остался".
Ложки не всегда находятся.
Код из "Р.Лафоре. ООП в С++"
Запись и чтение объектов разных классов в один файл
Запись и извлечение данных в несколько запусков программы
2
2688 / 2260 / 244
Регистрация: 03.07.2012
Сообщений: 8,231
Записей в блоге: 1
09.02.2016, 21:08
Интересная ссылка. Предположим, у меня есть проблема и нет (я не знаю) способа, как ее "честно" решить. Некто предлагает "хак", который работает и позволяет решить проблему. Я лично скажу ему "спасибо", даже если через 15 лет этот способ не сработает (на других ОС, для других компиляторов).

Был ли тогда офицальный, работающий механизм, который работает и сейчас? Дайте мне cсылку на него и я скажу, "да, Лафоре, тут Вы были не правы". А может и не скажу (мне нравятся те, кто исследует темные и малоизвестные места, а не просто собирает в кучу известное и обкатанное). Даже если сам способ перестал работать, заложенная в нем идея может быть полезна (идеи часто ценней реализации и живут дольше).
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
09.02.2016, 21:15
Цитата Сообщение от zer0mail Посмотреть сообщение
Некто предлагает "хак", который работает и позволяет решить проблему.
Это о коде Лафоре по ссылке? Или о чём?
0
2688 / 2260 / 244
Регистрация: 03.07.2012
Сообщений: 8,231
Записей в блоге: 1
09.02.2016, 21:27
Да, о нем, Как записать и потом прочитать множество объектов по ссылкам, зная только, что каждый из объектов либо класса X, либо какой-то из его наследников? И чтобы этот способ работал в 2001 году (когда вышло 4е издание)
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
09.02.2016, 22:07
Цитата Сообщение от zer0mail Посмотреть сообщение
Да, о нем, Как записать и потом прочитать множество объектов по ссылкам, зная только, что каждый из объектов либо класса X, либо какой-то из его наследников? И чтобы этот способ работал в 2001 году (когда вышло 4е издание)
Я думаю, что ничто не мешает заменить в его коде запись/чтение памяти под объектами, на запись/чтение членов-данных классов. Там же из-за этого ошибки появляются. Его "хак" никуда, при этом, не денется.
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
09.02.2016, 22:23
Цитата Сообщение от zer0mail Посмотреть сообщение
Я пока не понял, чего так наезжают на Лафоре
Ну, дебильность Лафоре и его "книг" очевидна любому вменяемому и знакомому с предметом читателю, и неоднократно обсуждалась здесь на форуме с цитатами и листингами, так что не очень понятно чего такого вы "не поняли". Ну, совсем "свежие" новички не в силах, конечно, самостоятельно оценить, но тем внимательнее должны прислушиваться к компетентным мнениям.
Конкретная дебильность программы из первого сообщения в том, что пользователь вводит чисел сколько хочет, а размер контейнера фиксированный. Тут уж надо или при фиксированном размере контейнера вводить элементов не больше, чем он может вместить, либо уже делать его безразмерным, вот так, например:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <algorithm>
#include <iostream>
#include <iterator>
#include <list>
///////////////////////////////////////////////////////////////////////////////
int main()
{
   std::setlocale( LC_ALL, "rus" );
   std::cout << "\nInput int numbers: ";
 
   std::istream_iterator<int> cin_iter(std::cin);
   std::istream_iterator<int> end_of_stream;
 
   std::list<int> fList     (
                                cin_iter,
                                end_of_stream
                            );
 
   std::cout << std::endl;
   std::ostream_iterator<int> ositer(std::cout, "\t");
   std::copy(fList.begin(), fList.end(), ositer);
   std::cout << std::endl;
}
0
2688 / 2260 / 244
Регистрация: 03.07.2012
Сообщений: 8,231
Записей в блоге: 1
09.02.2016, 22:43
nd2, Вы пишите процедуры записи/чтения класса, потом я пишу класс-наследник. Смогут процедуры правильно записать/прочитать объекты моего наследника?

Добавлено через 8 минут
Цитата Сообщение от Mr.X Посмотреть сообщение
Ну, дебильность Лафоре и его "книг" очевидна любому вменяемому и знакомому с предметом читателю,
Сомнительное утверждение. У Вас есть учебник, тиражи которого превышают тиражи книг Лафоре? Не надо путать учебный листинг с написанием реальных программ. Листинг - это дополнение к изложенному материалу и служит обучению, а не для демострации своей "крутизны". Что-то необходимо опускать и откладывать на потом.

Добавлено через 9 минут
Более того, хороший преподаватель должен раскидывать "грабли", чтобы студенты на них наступали, учились их видеть и уметь их обходить. Иначе "по курсу" все гладко, а по жизни "нифига не работает и непонятно, что делать".

Впрочем, если на форуме считается хорошим тоном обливать Лафоре грязью - это ваше дело. Но пусть молодежь знает, что есть и другая точка зрения.
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
09.02.2016, 22:55
Цитата Сообщение от zer0mail Посмотреть сообщение
Сомнительное утверждение.
Да сомневайтесь сколько хотите. Я вроде бы уже и на форум сослался. Вы читали эти отзывы? Или они тоже для вас "сомнительные"? При чем тут тиражи? Мы говорим о некомпетентности автора и о том, что в его книгах полно грубых ошибок и ляпов, говорящих о том, что, прежде чем учить, он забыл сам поучиться хоть немного. А тиражам, кстати, я в какой-то теме уже удивлялся. Да и вообще поражает такое массовое увлечение этой халтурой.

Добавлено через 7 минут
Цитата Сообщение от zer0mail Посмотреть сообщение
Впрочем, если на форуме считается хорошим тоном обливать Лафоре грязью
Ну, книга - это, так сказать, письмо в вечность. Поэтому засирание вечности халтурой - наглое и дерзкое интеллектуальное преступление, и хотя бы морального осуждения и презрения заслуживает.
1
2688 / 2260 / 244
Регистрация: 03.07.2012
Сообщений: 8,231
Записей в блоге: 1
09.02.2016, 22:56
Цитата Сообщение от Mr.X Посмотреть сообщение
Конкретная дебильность программы из первого сообщения в том, что пользователь вводит чисел сколько хочет, а размер контейнера фиксированный.
Это не дебильность программы - это дебильность некоторых читателей. Лафоре написал, как ввести 5 чисел и закончить ввод и показал, как использовать объект end_of_stream (а заодно, как его получить). Кто не понял - наступил на грабли и понял (или не понял) в чем они. Обходить эти грабли можно по разному - тут дело вкуса. На книгах одни учатся, другие - плюются. В общем, каждому - по способностям.
0
Эксперт С++
 Аватар для Mr.X
3225 / 1752 / 436
Регистрация: 03.05.2010
Сообщений: 3,867
09.02.2016, 23:02
Цитата Сообщение от zer0mail Посмотреть сообщение
Это не дебильность программы - это дебильность некоторых читателей.
Т.е. аргументы заканчиваются, начинаем на личности переходить? Ну да, не доросли мы до вашего Лафоре, хорошо, хоть вам Бог дал. Наслаждайтесь, чё.
0
2688 / 2260 / 244
Регистрация: 03.07.2012
Сообщений: 8,231
Записей в блоге: 1
09.02.2016, 23:09
Слово "дебильность" Вы первым использовали. Будет время - почитаю, как он описывает "тонкие" моменты. Может, чё интересное найду...
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
10.02.2016, 00:33
zer0mail, как вариант:
Кликните здесь для просмотра всего текста
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
// empl_io.cpp
// performs file I/O on employee objects
// handles different sized objects
#include <fstream>            //for file-stream functions
#include <iostream>
#include <typeinfo>           //for typeid()
using namespace std;
#include <process.h>          //for exit()
 
const int LEN = 32;           //maximum length of last names
const int MAXEM = 100;        //maximum number of employees
 
enum employee_type {tmanager, tscientist, tlaborer};
////////////////////////////////////////////////////////////////
class employee                //employee class
{
private:
    char name[LEN];         //employee name
    unsigned long number;   //employee number
    static int n;           //current number of employees
    static employee* arrap[];  //array of ptrs to emps
public:
    virtual void getdata()
    {
        cin.ignore(10, '\n');
        cout << "   Enter last name: "; cin >> name;
        cout << "   Enter number: ";      cin >> number;
    }
    virtual void putdata()
    {
        cout << "\n   Name: " << name;
        cout << "\n   Number: " << number;
    }
    virtual void toFile(ofstream& out)
    {
        out.write((const char*)name, LEN);
        out.write((const char*)&number, sizeof(number));
    }
    virtual void fromFile(ifstream& in)
    {
        in.read((char*)name, LEN);
        in.read((char*)&number, sizeof(number));
    }
    virtual ~employee()
    {}
 
    virtual employee_type get_type();  //get type
    static void add();      //add an employee
    static void display();  //display all employees
    static void read();     //read from disk file
    static void write();    //write to disk file
    static void delAll(); //delete all employees
};
//--------------------------------------------------------------
//static variables
int employee::n = 0;              //current number of employees
employee* employee::arrap[MAXEM];  //array of ptrs to emps
////////////////////////////////////////////////////////////////
//manager class
class manager : public employee
{
private:
    char title[LEN];        //"vice-president" etc.
    double dues;            //golf club dues
public:
    void getdata()
    {
        employee::getdata();
        cout << "   Enter title: ";          cin >> title;
        cout << "   Enter golf club dues: "; cin >> dues;
    }
    void putdata()
    {
        employee::putdata();
        cout << "\n   Title: " << title;
        cout << "\n   Golf club dues: " << dues;
    }
    virtual void toFile(ofstream& out)
    {
        employee::toFile(out);
        out.write((const char*)title, LEN);
        out.write((const char*)&dues, sizeof(dues));
    }
    virtual void fromFile(ifstream& in)
    {
        employee::fromFile(in);
        in.read((char*)title, LEN);
        in.read((char*)&dues, sizeof(dues));
    }
};
////////////////////////////////////////////////////////////////
//scientist class
class scientist : public employee
{
private:
    int pubs;               //number of publications
public:
    void getdata()
    {
        employee::getdata();
        cout << "   Enter number of pubs: "; cin >> pubs;
    }
    void putdata()
    {
        employee::putdata();
        cout << "\n   Number of publications: " << pubs;
    }
    virtual void toFile(ofstream& out)
    {
        employee::toFile(out);
        out.write((const char*)&pubs, sizeof(pubs));
    }
    virtual void fromFile(ifstream& in)
    {
        employee::fromFile(in);
        in.read((char*)&pubs, sizeof(pubs));
    }
 };
////////////////////////////////////////////////////////////////   
//laborer class
class laborer : public employee
{
};
////////////////////////////////////////////////////////////////
//add employee to list in memory
void employee::add()
{
    char ch;
    cout << "'m' to add a manager"
        "\n's' to add a scientist"
        "\n'l' to add a laborer"
        "\nEnter selection: ";
    cin >> ch;
    switch(ch)
    {                       //create specified employee type
    case 'm': arrap[n] = new manager;   break;
    case 's': arrap[n] = new scientist; break;
    case 'l': arrap[n] = new laborer;   break;
    default: cout << "\nUnknown employee type\n"; return;
    }
    arrap[n++]->getdata();     //get employee data from user
}
//--------------------------------------------------------------
//display all employees
void employee::display()
{
    for(int j=0; j<n; j++)
    {
        cout  << (j+1);           //display number
        switch( arrap[j]->get_type() )   //display type
        {
        case tmanager:    cout << ". Type: Manager";   break;
        case tscientist:  cout << ". Type: Scientist"; break;
        case tlaborer:    cout << ". Type: Laborer";   break;
        default: cout << ". Unknown type";
        }
        arrap[j]->putdata();    //display employee data
        cout << endl;
    }
}
//--------------------------------------------------------------
//return the type of this object
employee_type employee::get_type()
{
    if( typeid(*this) == typeid(manager) )
        return tmanager;
    else if( typeid(*this)==typeid(scientist) )
        return tscientist;
    else if( typeid(*this)==typeid(laborer) )
        return tlaborer;
    else
    { cerr << "\nBad employee type"; exit(1); }
    return tmanager;
}
//--------------------------------------------------------------
//write all current memory objects to file
void employee::write()
{
    //int size;
    cout << "Writing " << n << " employees.\n";
    ofstream ouf;              //open ofstream in binary
    employee_type etype;       //type of each employee object
 
    ouf.open("EMPLOY.DAT", ios::trunc | ios::binary);
    if(!ouf)
    { cout << "\nCan't open file\n"; return; }
    for(int j=0; j<n; j++)     //for every employee object
    {                       //get its type
        etype = arrap[j]->get_type();
        //write type to file
        ouf.write( (char*)&etype, sizeof(etype) );
        //switch(etype)           //find its size
        //{
        //case tmanager:   size=sizeof(manager); break;
        //case tscientist: size=sizeof(scientist); break;
        //case tlaborer:   size=sizeof(laborer); break;
        //}                    //write employee object to file
        //ouf.write( (char*)(arrap[j]), size );
        arrap[j] ->toFile(ouf);
        if(!ouf)
        { cout << "\nCan't write to file\n"; return; }
    }
}
//--------------------------------------------------------------
//read data for all employees from file into memory
void employee::read()
{
    //int size;                  //size of employee object
    employee_type etype;       //type of employee
    ifstream inf;              //open ifstream in binary
    inf.open("EMPLOY.DAT", ios::binary);
    if(!inf)
    { cout << "\nCan't open file\n"; return; }
    
    employee::delAll();
    
    n = 0;                     //no employees in memory yet
    while(true)
    {                       //read type of next employee
        inf.read( (char*)&etype, sizeof(etype) );
        if( inf.eof() )         //quit loop on eof
            break;
        if(!inf)                //error reading type
        { cout << "\nCan't read type from file\n"; return; }
        switch(etype)
        {                    //make new employee
        case tmanager:       //of correct type
            arrap[n] = new manager;
            //size=sizeof(manager);
            break;
        case tscientist:
            arrap[n] = new scientist;
            //size=sizeof(scientist);
            break;
        case tlaborer:
            arrap[n] = new laborer;
            //size=sizeof(laborer);
            break;
        default: cout << "\nUnknown type in file\n"; return;
        }                    //read data from file into it
        //inf.read( (char*)arrap[n], size  );
        arrap[n] ->fromFile(inf);
        if(!inf)                //error but not eof
        { cout << "\nCan't read data from file\n"; return; }
        n++;                    //count employee
    }  //end while
    cout << "Reading " << n << " employees\n";
}
 
void employee::delAll()
{
    for (int i = 0; i < n; ++i)
        delete arrap[i];
}
////////////////////////////////////////////////////////////////
int main()
{
    char ch;
    while(true)
    {
        cout << "'a' -- add data for an employee"
            "\n'd' -- display data for all employees"
            "\n'w' -- write all employee data to file"
            "\n'r' -- read all employee data from file"
            "\n'x' -- exit"
            "\nEnter selection: ";
        cin >> ch;
        switch(ch)
        {
        case 'a':            //add an employee to list
            employee::add(); break;
        case 'd':            //display all employees
            employee::display(); break;
        case 'w':            //write employees to file
            employee::write(); break;
        case 'r':            //read all employees from file
            employee::read(); break;
        case 'x':
            {
                employee::delAll();
                
                exit(0);   //exit program
            }
        default: cout << "\nUnknown command";
        }  //end switch
    }  //end while
    
    return 0;
}  //end main()
0
Эксперт С++
4986 / 3093 / 456
Регистрация: 10.11.2010
Сообщений: 11,170
Записей в блоге: 10
10.02.2016, 00:46
Mr.X, zer0mail, будьте умнее. Не продолжайте спор.
0
nd2
3438 / 2817 / 1249
Регистрация: 29.01.2016
Сообщений: 9,427
10.02.2016, 00:54
zer0mail, в коде Лафоре, кстати, ещё утечка памяти присутствует: имею в виду, не в конце кода (это ладно, система освободит), а в employee::read(). Если выбрано чтение, а массив указателей уже существует, то старые указатели просто затираются новыми, память, естественно, утекает.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
10.02.2016, 00:54
Помогаю со студенческими работами здесь

Не могу создать вектор, используя потоковые итераторы напрямую
#include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;algorithm&gt; #include &lt;iterator&gt; #include &lt;string&gt; using namespace std; int...

C++: итераторы по умолчанию, пустые итераторы, end()
Всем добра! Вопрос на тему итераторов в плюсах: 1. какие значения имеют итераторы без инициализации например,...

STL. Не работает вывод через << в поток когда использую итераторы :(
Вроде бы ничего сложного, но почему-то работать не хочет. Никак не могу понять почему ( Ругается, когда пишу void main() { ...

Итераторы и обратные итераторы
У вектора есть два типа итераторов, обычные и обратные итераторы произвольного доступа... Обычные реализовал, осталось обратные. Решил...

Лутц : "Итераторы и генераторы" - не работает пример
Всем привет. В программировании можно сказать я ноль - читаю Лутца последнее время и столкнулся со следующим примером: (скрин во...


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

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru