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

Можно ли при чтении из файла элементов в список удалять эти элементы(без очистки файла)

30.06.2019, 12:59. Показов 839. Ответов 4
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Допустим,есть файл,в нём записаны 3 обьекта(отличаются одним параметром,по которому как раз и достаются обьекты из файла).Пусть второй обьект считается из файла.Можно ли как-то сделать так,чтобы он удалялся из файла?
Вот метод загрузки из файла:
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
template <typename T>
int List<T>::LoadList1(const char* s)
{
    std::ifstream f("Phones.txt");
    if(!f.is_open())                                                 
    {                                                       
        std::cout << "------------------------------------------------------------------------------------------------------------------------" << std::endl;
        std::cout << " Ошибка открытия файла!" << std::endl;
        return 0;                                            
    }
    int Count;
    f >> Count;
    std::cout << Count;
    for(int i = 0; i < Count; i++)
        {
            char Identificator[25];
            char PhoneName[30];
            char PhoneFabricator[20];
            char PhoneColor[20];
            float PhoneWeight;
            int PhoneNumberOfSIMCards;
            float PhoneScreenDiagonal;
            char PhoneTouchScreen[12];
            char PhoneTypeOfShell[20];
            f >> Identificator;
            if ((strcmp(Identificator,s)==0))
            //if (strspn(Identificator,s)==strlen(Identificator))
                {
                    f >> PhoneName;
                    f >> PhoneFabricator;
                    f >> PhoneColor;
                    f >> PhoneWeight;
                    f >> PhoneNumberOfSIMCards;
                    f >> PhoneScreenDiagonal;
                    f >> PhoneTouchScreen;
                    f >> PhoneTypeOfShell;
                    auto cell = new Cell (PhoneFabricator,PhoneName,PhoneColor,PhoneWeight,PhoneNumberOfSIMCards,PhoneScreenDiagonal,PhoneTouchScreen,PhoneTypeOfShell);
                    push_back(*cell);//T*
                    free(cell);
                }
        }
    f.close();
    return 1;
}
s - строка которая вводится вручную при использовании функции.
Файл выглядит так:
3
123CElLtE
333
333
333
333
333
333
333
333
SmA1TP1
111
111
111
111
111
111
111
111
C01dLp12
444
444
444
444
444
444
444
444
3 в первой строке - число элементов, записанных в файл
Мне нужно, чтобы было так:
Программа считывает первую строку в переменную int Count,и сразу удаляется(можно и после считывания обьекта)
Далее программа проверяет условие, и если всё правильно, то происодит построчное считывание параметров обьекта,а затем эти параметры удаляются из файла без его перезаписи. Это можно как-то сделать? Желательно без большого кода.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.06.2019, 12:59
Ответы с готовыми решениями:

Как при чтении файла проверить достигнут ли конец файла?
Как при чтении файла проверить достигнут ли конец файла? Dim Red As IO.BinaryReader Red = New...

"Нарушение прав доступа при чтении по адресу" при чтении структур из бинарного файла
Пытаюсь разобраться со структурами в бинарных файлах. Допустим, есть массив структур. Записываю его в бинарный файл (закомментированный...

За один просмотр файла и без использования дополнительных файлов вывести элементы файла f в указанном порядке
Если можете сделайте программу (сам пытался понять как делать но не получается +времени нет готовлюсь к экзамену) За один просмотр...

4
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
30.06.2019, 20:09
Цитата Сообщение от Денис73 Посмотреть сообщение
а затем эти параметры удаляются из файла без его перезаписи. Это можно как-то сделать?
В том виде, как это у вас сейчас есть - нельзя. Это во-первых.

Во-вторых, ваша функция будет работать неправильно если при последовательных вызовах функции значения пареметра s будут отличаться от считываемых значений для поля Identificator. Т.е. будет работать до первого несовпадения в строке 26.

В-третьих, у меня стойкое ощущение, что вы делаете не то и не так. Поэтому и имеете проблемы. Но поскольку общая задача неизвестна, что-либо посоветовать затруднительно.
0
3 / 3 / 1
Регистрация: 08.03.2019
Сообщений: 71
30.06.2019, 20:31  [ТС]
В общем,у меня есть дерево из 7 классов(1 базовый,2 потомка и 4 внука). От 4 внуков я создаю 4 вида обьекта и записываю в односвязный список.Затем записываю список в файл.Изначально я записываю только обьекты только одного внука,а затем в файл.На этом этапе всё работает.Но мне дали задание сделать так,чтобы все списки записывались в один файл. И вот тут уже возникают проблемы,т.к. для того,чтобы записать что-либо,нужно считать данные из файла,т.к. файл перед записью очищается. Поэтому я подумал,что можно выборочно читать обьекты,но в итоге я застрял на том,что,как вы сказали,если условие не выполнится,то чтение будет происходить только для первого обьекта и неуспешно.
0
3 / 3 / 1
Регистрация: 08.03.2019
Сообщений: 71
30.06.2019, 20:32  [ТС]
Вот полный класс односвязного списка:
List.cpp
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
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//   Конструктор копирования
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
List<T>::List(const List<T>& src):
head(NULL), tail(NULL), count(0)                                        // Изначально новый список пустой
{
    Node<T>* current = src.head;                                        // Создаём current и присваиваем
                                                                        // ей новое начало списка
    while (current != NULL)                                             // Выполняем цикл,пока current равна NULL
    {
        this->push_back(current->data);                                 // Добавляем элемент в конец этого списка
        current = current->next;                                        // и перемещаем current вперёд на один элемент
    }
 
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//   Деструктор
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
List<T>::~List()
{
    clear();                                                            // Вызов метода очистки списка
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//   Очистка списка
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
void List<T>::clear()
{
    while (! this->empty())                                             // Пока список не пустой,
    {
        this->pop_front();                                              // удаляем элементы с начала
    }
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//   Добавить элемент в начало
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
void List<T>::push_front(T d)
{
    Node<T>* new_head = new Node<T>(d, head);
    if (this->empty())                                                  // Если список пуст,то новый элемент
    {                                                                   // станет и началом, и концом списка
        head = new_head;
        tail = new_head;
    }
    else                                                                // Иначе добавляем элемент в начало списка
    {
        head = new_head;
    }
    count++;                                                            // Смещаемся вперёд
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//   Добавить элемент в конец
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
void List<T>::push_back(T d)
{
    Node<T>* new_tail = new Node<T>(d, NULL);                           // Выделяем динамическую память
                                                                        // для пового конца списка
    if (this->empty())                                                  // Если список пуст,то новый элемент
    {                                                                   // станет началом списка
        head = new_tail;
    }
    else
    {
        tail->next = new_tail;                                          // Иначе добавляем элемент в конец списка
    }
    tail = new_tail;                                                    // и смещаем конец списка
    count++;                                                            // Смещаемся вперёд
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//   Удалить элемент из начала
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
void List<T>::pop_front()
{
    assert(head != NULL);                                               // Если конец списка равен NULL,
                                                                        // функция assert немедленно завершает метод
    Node<T>* old_head = head;                                           // Резервируем место для текущего начала списка
    if (this->size() == 1)                                              // Если в списке один элемент, то
    {                                                                   // очищаем его
        head = NULL;
        tail = NULL;
    }
    else                                                                // Иначе смещаем начало списка
    {
            head = head->next;                                          // на один элемент вперёд
    }
    delete old_head;                                                    // и удаляем оставшийся позади элемент
    count--;                                                            // Смещаемся назад
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//   Удалить элемент из конца
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
void List<T>::pop_back(void)
{
    assert(tail != NULL);                                               // Если конец списка равен NULL,
                                                                        // функция assert немедленно завершает метод
    Node<T>* old_tail = tail;
    if (this->size() == 1)                                              // Если в списке один элемент, то
    {                                                                   // очищаем его
        head = NULL;
        tail = NULL;
    }
    else                                                                // Иначе перемещаемся в конец списка
    {                                                                   // с помощью current
        Node<T>* current = head;                                        // Для начала приравниваем её к началу списка,
        while (current->next != tail)                                   // затем выполняем цикл, пока не дошли до конца:
        {
            current = current->next;                                    // Смещаем current вперёд на один элемент
        }                                                               // Когда доходим до конца,
        current->next = NULL;                                           // смещаемся ещё на один элемент
                                                                        // и приравниваем этот элемент к NULL
        tail = current;                                                 // Затем приравниваем концу списка
    }                                                                   // currect, которая равна NULL
    delete old_tail;                                                    // Очищаем старый конец списка
    count--;                                                            // Смещаемся назад
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//   Распечатать список
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
void List<T>::PrintList(void)
{
    Node<T>* current = head;                                            // Создаём новую переменную
                                                                        // и приравниваем к ней начало списка
    if (current != NULL)                                                // Если список не пустой,
    {
        while (current!= NULL)                                          // То выполняем цикл до тех пор,
        {                                                               // пока список не пустой:
            std::cout << current->data;                                 // выводим элемент списка и
            current = current->next;                                    // смещаемся на один элемент вперёд
        }
    }
    else std::cout << " Список пуст!" << std::endl;
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//   Сохранить список в файл
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
void List<T>::SaveList()
{
    std::ifstream f1;
    f1.open("Phones.txt",std::ios::out);
    int Count;
    f1 >> Count;
    Count = Count + count;
    f1.close();
    std::ofstream f;
    f.open("Phones.txt",std::ios::app);
    f << Count << std::endl;
    f.close();
    Node<T>* current = head;
    if (current != NULL)
    {
        while (current!= NULL)
        {
            current->data.Save();
            current = current->next;
        }
    }
}
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//   ЗАгрузить список из файла
//---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
int List<T>::LoadList1(const char* s)
{
    std::ifstream f("Phones.txt");
    if(!f.is_open())                                                    // Если файл не открывается, то
    {                                                                   // информируем об этом
        std::cout << "------------------------------------------------------------------------------------------------------------------------" << std::endl;
        std::cout << " Ошибка открытия файла!" << std::endl;
        return 0;                                                       // и возвращаем 0
    }
    int Count;
    f >> Count;
    std::cout << Count;
    for(int i = 0; i < Count; i++)
        {
            char Identificator[25];
            char PhoneName[30];
            char PhoneFabricator[20];
            char PhoneColor[20];
            float PhoneWeight;
            int PhoneNumberOfSIMCards;
            float PhoneScreenDiagonal;
            char PhoneTouchScreen[12];
            char PhoneTypeOfShell[20];
            f >> Identificator;
            if ((strcmp(Identificator,s)==0))
            //if (strspn(Identificator,s)==strlen(Identificator))
                {
                    f >> PhoneName;
                    f >> PhoneFabricator;
                    f >> PhoneColor;
                    f >> PhoneWeight;
                    f >> PhoneNumberOfSIMCards;
                    f >> PhoneScreenDiagonal;
                    f >> PhoneTouchScreen;
                    f >> PhoneTypeOfShell;
                    auto cell = new Cell (PhoneFabricator,PhoneName,PhoneColor,PhoneWeight,PhoneNumberOfSIMCards,PhoneScreenDiagonal,PhoneTouchScreen,PhoneTypeOfShell);
                    push_back(*cell);//T*
                    free(cell);
                }
        }
    f.close();
    return 1;
}
template <typename T>
int List<T>::LoadList2(const char* s)
{
    std::ifstream f("Phones.txt");
    if(!f.is_open())                                                    // Если файл не открывается, то
    {                                                                   // информируем об этом
        std::cout << "------------------------------------------------------------------------------------------------------------------------" << std::endl;
        std::cout << " Ошибка открытия файла!" << std::endl;
        return 0;                                                       // и возвращаем 0
    }
    int Count;
    f >> Count;
    std::cout << Count;
    for(int i = 0; i < Count; i++)
        {
            char Identificator[25];
            char PhoneName[30];
            char PhoneFabricator[20];
            char PhoneColor[20];
            float PhoneWeight;
            int PhoneNumberOfSIMCards;
            float PhoneScreenDiagonal;
            int PhoneROM;
            int PhoneRAM;
            f >> Identificator;
            if ((strcmp(Identificator,s)==0))
            //if (strspn(Identificator,s)==strlen(Identificator))
                {
                    f >> PhoneName >> PhoneFabricator >> PhoneColor >> PhoneWeight >> PhoneNumberOfSIMCards >> PhoneScreenDiagonal >> PhoneROM >> PhoneRAM;
                    auto smart = new Smartphones (PhoneName,PhoneFabricator,PhoneColor,PhoneWeight,PhoneNumberOfSIMCards,PhoneScreenDiagonal,PhoneROM,PhoneRAM);
                    push_back(*smart);//T*
                }
        }
    f.close();
    return 1;
}
template <typename T>
int List<T>::LoadList3(const char* s)
{
    std::ifstream f("Phones.txt");
    if(!f.is_open())                                                    // Если файл не открывается, то
    {                                                                   // информируем об этом
        std::cout << "------------------------------------------------------------------------------------------------------------------------" << std::endl;
        std::cout << " Ошибка открытия файла!" << std::endl;
        return 0;                                                       // и возвращаем 0
    }
    int Count;
    f >> Count;
    std::cout << Count;
    for(int i = 0; i < Count; i++)
        {
            char Identificator[25];
            char PhoneName[30];
            char PhoneFabricator[20];
            char PhoneColor[20];
            float PhoneWeight;
            char PhoneCallerID[12];
            char PhoneBuiltInNotebook[15];
            char PhoneMaterial[25];
            int PhoneRangeOfAction;
            f >> Identificator;
            if ((strcmp(Identificator,s)==0))
            //if (strspn(Identificator,s)==strlen(Identificator))
                {
                    f >> PhoneName >> PhoneFabricator >> PhoneColor >> PhoneWeight >> PhoneCallerID >> PhoneBuiltInNotebook >> PhoneMaterial >> PhoneRangeOfAction;
                    auto cordless = new Cordlessphones (PhoneName,PhoneFabricator,PhoneColor,PhoneWeight,PhoneCallerID,PhoneBuiltInNotebook,PhoneMaterial,PhoneRangeOfAction);
                    push_back(*cordless);//T*
                }
        }
    f.close();
    return 1;
}
template <typename T>
int List<T>::LoadList4(const char* s)
{
    std::ifstream f("Phones.txt");
    if(!f.is_open())                                                    // Если файл не открывается, то
    {                                                                   // информируем об этом
        std::cout << "------------------------------------------------------------------------------------------------------------------------" << std::endl;
        std::cout << " Ошибка открытия файла!" << std::endl;
        return 0;                                                       // и возвращаем 0
    }
    int Count;
    f >> Count;
    std::cout << Count;
    for(int i = 0; i < Count; i++)
        {
            char Identificator[25];
            char PhoneName[30];
            char PhoneFabricator[20];
            char PhoneColor[20];
            float PhoneWeight;
            char PhoneCallerID[12];
            char PhoneBuiltInNotebook[15];
            char PhoneDisplay[15];
            int PhoneLineInput;
            f >> Identificator;
            if ((strcmp(Identificator,s)==0))
            //if (strspn(Identificator,s)==strlen(Identificator))
                {
                    f >> PhoneName >> PhoneFabricator >> PhoneColor >> PhoneWeight >> PhoneCallerID >> PhoneBuiltInNotebook >> PhoneDisplay >> PhoneLineInput;
                    auto wire = new Wired (PhoneName,PhoneFabricator,PhoneColor,PhoneWeight,PhoneCallerID,PhoneBuiltInNotebook,PhoneDisplay,PhoneLineInput);
                    push_back(*wire);//T*
                }
        }
    f.close();
    return 1;
}
}
List.h:
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
template <typename T> class List;                           // Определяем дружественные классы для итераторов
template <typename T> class Iterator;                       // по соответствующим контейнерным классам
 
 
template <typename T>
class Node                                                  // Создаём класс для определения типов данных
    {                                                       // и переменной смещения
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
        friend class List<T>;                               // Задаём дружественность классам
        friend class Iterator <T>;                          // итератора и списка
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    private:
        T data;                                             // Задаём тип данных списка
        Node* next;                                         // задаём переменную смещения
 
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    public:
        Node(T d, Node* n = NULL) : data(d), next(n) {}     // Задаём их начальное значение через конструктор
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    };
 
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
class List                                                  // Создаём класс списка
{
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
private:
    Node<T>* head;                                          // Задаём начало списка
    Node<T>* tail;                                          // Задаём конец списка
    int count;                                              // Задаём переменную для нумерации элементов списка
 
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public:
    typedef Iterator<T> iterator;                           // Задаём синоним для для типа данных
 
    List(const List<T>& src);                               // Конструктор копирования
    ~List();                                                // Деструктор
    void clear();                                           // Очистка списка
    List() : head(NULL), tail(NULL), count(0) {}            // Конструктор
 
    int size() {return count;}                              // Возвращает переменную count
    bool empty() {return count == 0;}                       // Возвращает true,если count равен 0
 
    void push_front(T);                                     // Добавить элемент в начало
    void push_back(T);                                      // Добавить элемент в конец
 
    void pop_front();                                       // Удалить элемент из начала
    void pop_back();                                        // Удалить элемент из конца
 
    void SaveList();                                        // Сохранить список в файл
    int LoadList(const char* s);                            // Загрузка списка из файла
 
    int LoadList1(const char* s);                            // Загрузка списка из файла
    int LoadList2(const char* s);                            // Загрузка списка из файла
    int LoadList3(const char* s);                            // Загрузка списка из файла
    int LoadList4(const char* s);                            // Загрузка списка из файла
 
    void PrintList();                                       // Распечатать список
 
    Iterator<T> begin()                                     // Перемещаем итератор в начало списка
    {
        return Iterator<T>(head);
    }
    Iterator<T> end()                                       // Перемещаем итератор в конец списка
    {
        return Iterator<T>(tail);
    }
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
};
 
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
template <typename T>
class Iterator                                              // Создаём класс итератора
{
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
private:
    Node<T> *target;                                        // Задаём элемент итератора для работы со списком
 
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
public:
    Iterator() {}                                           // Конструктор
    Iterator(Node<T> *target) : target(target) {}           // Задаём начальное значение target
 
    T& operator*()                                          // Перегружаем оператор непрямого обращения
        {
            return target->data;
        }
    T* operator->()                                         // Перегружаем оператор обращения к члену структуры
        {
            return &target->data;
        }
    Iterator& operator++()                                  // Перегружаем оператор инкремент(префиксный)
    {
        target = target->next;
        return *this;
    }
    Iterator operator++(int)                                // Перегружаем оператор инкремент(постфиксный)
    {
        target = target->next;
        return *this;
    }
    bool operator==(Iterator const& r)                      // Перегружаем оператор равенста
        {
            return (target == r.target);
        }
    bool operator!=(Iterator const& r)                      // Перегружаем оператор неравенства
        {
            return (target != r.target);
        }
/*----------------------------------------------------------------------------*/
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
};
0
Мозгоправ
 Аватар для L0M
1745 / 1039 / 468
Регистрация: 01.10.2018
Сообщений: 2,138
Записей в блоге: 2
06.07.2019, 03:22
Цитата Сообщение от Денис73 Посмотреть сообщение
Но мне дали задание сделать так,чтобы все списки записывались в один файл.
Денис73, сколько у вас должно быть списков? Четыре? В каждом из которых телефоны одного типа. Или один список, в котором хранятся телефоны разных типов? Потому что вышепроцитированное требование звучит странно, если у вас 4 разных списка. Хотя и реализуемо. Это 1.

2. Зачем вы полезли править класс List<T>? Кроме того, что вы привязали обобщённый шаблонный контейнерный класс к своим типам и данным, вы разнесли его на заголовочный файл (List.h) и файл реализации (List.cpp). Ни один из известных мне компиляторов такую возможность не поддерживает - реализации шаблонных методов должны находиться в заголовочном файле.

В остальном класс List<T> написан неплохо. Единственно не учтено то обстоятельство, что T может быть указателем. При этом в методах pop_front() и pop_back() может происходить утечка памяти: в них удаляется объект типа Node, но если Node в поле data содержит указатель на другой объект в динамической памяти, то адрес этого объекта будет утерян.

3. Если есть желание оформить базу данных телефонных аппаратов в стиле ООП, то создайте ещё один класс PhoneDB, в который поместите список (или 4 списка) с данными по аппаратам и напишите необходимые методы для работы с ним(и): запись в файл, чтение из файла, вывод на консоль и пр.

4. Не думаю, что выборочная загрузка данных по одному аппарату из файла, это хорошая идея (имеется ввиду вот это: if ((strcmp(Identificator, s) == 0))). Читайте из файла все данные. Добавление, изменение, удаление делайте в памяти посредством вызовов методов класса List. Потом все данные, если были сделаны какие-то изменения, записывайте в файл.

5. Есть большое подозрение, что вы неправильно построили иерархию классов телефонных аппаратов, если судить по строкам 184-205 в List.cpp и аналогичным фрагментам далее.

Если схематично, то иерархия должна выглядеть примерно так:
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
#include <iostream>
 
using namespace std;
 
class Phone {
public:
    Phone() { /* инициализация*/ }
 
    virtual bool write(ostream &os) const {
        os.write(Identificator, sizeof(Identificator));
        os.write(PhoneName, sizeof(PhoneName));
        os.write(PhoneFabricator, sizeof(PhoneFabricator));
        os.write(PhoneColor, sizeof(PhoneColor));
        os.write((const char *)&PhoneWeight, sizeof(PhoneWeight));
        return os.good();
    }
 
    virtual bool read(istream &is) {
        is.read(Identificator, sizeof(Identificator));
        is.read(PhoneName, sizeof(PhoneName));
        is.read(PhoneFabricator, sizeof(PhoneFabricator));
        is.read(PhoneColor, sizeof(PhoneColor));
        is.read((char *)&PhoneWeight, sizeof(PhoneWeight));
        return is.good();
    }
 
    virtual ostream& print(ostream &os) const {
        return os
            << Identificator << endl
            << PhoneName << endl
            << PhoneFabricator << endl
            << PhoneColor << endl
            << PhoneWeight << endl;
    }
 
protected:
    char Identificator[25];
    char PhoneName[30];
    char PhoneFabricator[20];
    char PhoneColor[20];
    float PhoneWeight;
};
 
class Mobile : public Phone {
public:
    Mobile() { /* инициализация*/ }
 
    virtual bool write(ostream &os) const override {
        Phone::write(os);
        os.write((const char *)&PhoneNumberOfSIMCards, sizeof(PhoneNumberOfSIMCards));
        os.write((const char *)&PhoneScreenDiagonal, sizeof(PhoneScreenDiagonal));
        return os.good();
    }
 
    virtual bool read(istream &is) override {
        Phone::read(is);
        is.read((char *)&PhoneNumberOfSIMCards, sizeof(PhoneNumberOfSIMCards));
        is.read((char *)&PhoneScreenDiagonal, sizeof(PhoneScreenDiagonal));
        return is.good();
    }
 
    virtual ostream& print(ostream &os) const override {
        Phone::print(os);
        return os
            << PhoneNumberOfSIMCards << endl
            << PhoneScreenDiagonal << endl;
    }
 
protected:
    int PhoneNumberOfSIMCards;
    float PhoneScreenDiagonal;
};
 
class Stationary : public Phone {
public:
    Stationary();
    virtual bool write(ostream &os) const override;
    virtual bool read(istream &is) override;
    virtual ostream& print(ostream &os) const override;
protected:
    char PhoneCallerID[12];
    char PhoneBuiltInNotebook[15];
 
};
 
class Cell : public Mobile {
public:
    Cell();
    virtual bool write(ostream &os) const override;
    virtual bool read(istream &is) override;
    virtual ostream& print(ostream &os) const override;
private:
    char PhoneTouchScreen[12];
    char PhoneTypeOfShell[20];
};
 
class Smartphone : public Mobile {
public:
    Smartphone();
    virtual bool write(ostream &os) const override;
    virtual bool read(istream &is) override;
    virtual ostream& print(ostream &os) const override;
private:
    int PhoneROM;
    int PhoneRAM;
};
 
class Cordlessphone : public Stationary {
public:
    Cordlessphone();
    virtual bool write(ostream &os) const override;
    virtual bool read(istream &is) override;
    virtual ostream& print(ostream &os) const override;
private:
    char PhoneMaterial[25];
    int PhoneRangeOfAction;
};
 
class Wired : public Stationary {
public:
    Wired();
    virtual bool write(ostream &os) const override;
    virtual bool read(istream &is) override;
    virtual ostream& print(ostream &os) const override;
private:
    char PhoneDisplay[15];
    int PhoneLineInput;
};
Обратите внимание, что каждый класс должен уметь обслуживать свои данные: прочитать из потока, записать в поток, вывести в тектовый поток в читабельном виде (для вывода на консоль) и т.п. Для базового класса и одного сына я вам даже реализацию написал для ввода/вывода в двоичный поток и вывод в текстовый поток что бы продемонстрировать как должен работать весь этот механизм.

Понятно, что для каждого класса нужно дописать геттеры/сеттеры, реализацию конструктора и пр.

При такой иерархии все описания телефонов можно хранить четырёх списках типов List<Cell>, List<Smartphone>, List<Cordlessphone>, List<Wired>, а при обработке объектов из этих списков использовать Phone*, т.е. указатель на базовый класс. При вызовах виртуальных методов экземпляра класса через указатель на базовый класс будут вызываться методы нужного класса.

Также описания телефонов можно хранить в одном списке типа List<Phone*>. При этом нужно будет доработать класс List<T>, что бы избежать утечек памяти.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.07.2019, 03:22
Помогаю со студенческими работами здесь

Очередь. За один просмотр файла без использования дополнительных файлов напечатать элементы файла в порядке
HELP!!!HELP!!!HELP!!!HELP!!!HELP!!!HELP!!!HELP!!!HELP!!!HELP!!!HELP!!!HELP!!!HELP!!!HELP!!!HELP!!!HELP!!! Используя очередь, решить...

Дописывать в файл текст, удалять строки из файла и распечатывать на экране содержимое файла
Здравствуйте! Помогите пожалуйста написать командный фал. Разработать командный файл, который в интерактивном режиме мог бы...

Ошибка при чтении из файла
Помогите разобраться с чтением из файла. Листинг указан ниже. Программа выполняется полностью, и только перед выполнением последней строки...

Ошибка при чтении файла
нужна помощь я хотел сделать так, чтобы текст из файла зачитывался в буфер и после был записан в STATIC, но при компиляции программа не...

Ошибка при чтении файла
SEGM segment assume CS:SEGM, DS:SEGM, ES:SEGM, SS:SEGM org 100h Begin: ;open file mov ah,3dh ; функция открытия файла mov...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru