Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 26.07.2019
Сообщений: 9
1

Долговой журнал магазина

29.08.2019, 23:22. Показов 1011. Ответов 2
Метки нет (Все метки)

Доброго здравия, дорогие форумчане. Программировать я еще только учусь. Хочу написать долговой журнал магазина, который состоит из записей клиентов и их долговой историей (мысль навеяна весьма неудобным бумажным журналом в нашем деревенском магазине ). Написал два класса: customers (хранит данные клиента и его долговую историю) и customersList (для хранения списка клиентов и их совокупного долга перед магазином). В будущем надеюсь подружить этот код с c++/cli.
Сейчас возникла такая проблема: при попытке добавить второго клиента в список,
C++
1
2
3
    customersList list;
    list.addCustomer("Vasya Pupkin");
    list.addCustomer("Viktor");
программа вылетает.
Ниже сам код. В самом низу, закомментированные строчки, это - рабочий код без использования класса customersList. Подскажите пожалуйста, что не так, а то глаз уже замылен и голова совсем не соображает. Так же буду рад дельным замечаниям и рацпредложениям.



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
#pragma once
#include <iostream>
#include <vector>
 
using namespace std;
//char* lastDate =  String::Format("{0:f}\n".DateTime::Now);
 
class customers     //данные  клиента
    {   
        char name[35];      //имя
        char phone[20];     //телефон 
        char adress[50];    //адрес
        double fulldebt;    //общий долг
 
        struct history  //элемент долговой истории
        {
            char date[16];  //дата
            double debt;    //долг
            /*конструктор долга*/
            history(const char* _date, double _debt)
            {
                for (int i = 0; *(_date + i) != '\0'; i++)
                {
                    this->date[i] = _date[i];
                    if (*(_date + i + 1) == '\0') *(this->date + i + 1) = '\0';
                }
                this->debt = _debt;
            } 
        };
 
        std::vector<history>* his;//долговая история
 
    public:
 
        /****Constructors********/
        customers(const char* _name)
        {
            for (int i = 0; *(_name + i) != '\0'; i++)
            {
                this->name[i] = _name[i];
                if (*(_name + i + 1) == '\0') *(this->name + i + 1) = '\0';
            }
 
            his = new vector<history>;
        }
        customers(const char* _name, const char* _phone, const char* _adress):customers(_name)
        {
            for (int i = 0; *(_phone + i) != '\0'; i++)
            {
                this->phone[i] = _phone[i];
                if (*(_phone + i + 1) == '\0') *(this->phone + i + 1) = '\0';
            }
            for (int i = 0; *(_adress + i) != '\0'; i++)
            {
                this->adress[i] = _adress[i];
                if (*(_adress + i + 1) == '\0') *(this->adress + i + 1) = '\0';
            }
        }
 
        ~customers()
        {
            delete his;
        }
 
        /******Getters********/
        char* GetName()
        {
            return this->name;
        }
        char* GetPhone()
        {
            return this->phone;
        }
        char* GetAdress()
        {
            return this->adress;
        }
        char* GetLastDate()
        {
            return this->his->back().date;
        }
        double GetFullDebt()
        {
            return this->fulldebt;
        }
 
        /**********Setters**********/
        void SetName(char* _name)
        {
            for (int i = 0; *(_name + i) != '\0'; i++)
            {
                this->name[i] = _name[i];
                if (*(_name + i + 1) == '\0') *(name + i + 1) = '\0';
            }
        }
        void SetPhone(char* _phone)
        {
            for (int i = 0; *(_phone + i) != '\0'; i++)
            {
                this->phone[i] = _phone[i];
                if (*(_phone + i + 1) == '\0') *(phone + i + 1) = '\0';
            }
        }
        void SetAdress(char* _adress)
        {
            for (int i = 0; *(_adress + i) != '\0'; i++)
            {
                this->adress[i] = _adress[i];
                if (*(_adress + i + 1) == '\0') *(adress + i + 1) = '\0';
            }
        }
 
        /**********Methods**********/
        void AddDebt(const char* _date, double _debt)
        {
            this->his->push_back(history(_date,_debt));
            this->fulldebt += _debt;
        }
        void out()
        {
 
            for (unsigned int i = 0; i < this->his->size(); i++)
            {
                cout << this->his->at(i).date << "\t" << this->his->at(i).debt << endl;
            }
        }
 
};
 
 
class customersList //список покупателей
{
    double alldebts;
    vector<customers>* c_list;
 
    int length(const char* string) //вычисляем длину строки
    {
        int i = 0;
        while (string[i] != '\0')
        {
            i++;
        }
        return i;
    }
 
    int compare(const char* _name)  //сравниваем строку с именем покупателя
    {
        unsigned int index = 0;     //позиция покупателя в листе
        while (index <= c_list->size())
        {
            int len = length(_name);                //длина строки которую ищем
            char* tmp = c_list->at(index).GetName();    //длина имени
            if (len != length(tmp)) index++;        //если длины строк разные, то увеличиваем index для поиска в следующей позиции
            else {
                for (int i = 0; i <= len; i++)      //если длины строк одинаковы, то проверяем их содержимое на совпадение 
                {
                    if (tmp[i] != _name[i]) {       //если содержимое строк разное, то увеличиваем index и выходим из цикла
                        index++; break;
                    }
                } return index;                 //если сравнение закончилось успешно, то возвращаем index вызывателю
            }
        }
        return -1;  //если позиции закончились, а совпадений не найдено, возвращаем -1, как знак ошибки
 
    }
 
 
public:
 
    customersList()
    {
        c_list = new vector<customers>;
    }
 
    ~customersList()
    {
        delete c_list;
    }
 
    void addCustomer(const char* _name)
    {
        c_list->push_back(customers(_name));
    }
 
    void addCustomer(const char* _name, const char* _phone, const char* _adress)
    {
        c_list->push_back(customers(_name, _phone, _adress));
    }
    
    void addDebt(const char* _name, const char* _date, double _debt)
    {
        c_list->at(compare(_name)).AddDebt(_date, _debt);
    }
 
    void out(const char* _name)
    {
        int index = compare(_name);
        //c_list->at(index).out();
        cout << c_list->at(index).GetName() << "\t" << c_list->at(index).GetPhone() << "\t" << c_list->at(index).GetAdress() << endl;
    }
 
};
 
 
int main()
{
    customersList* list = new customersList();
    list->addCustomer("Vasya Pupkin");
    list->addCustomer("Viktor");
    list->addCustomer("Nikita", "+7(978)897-54-65", "pos. Kurortnoe, ul. Nikitinoy 30");
    list->addDebt("Nikita", "15.02.2014", 150);
    
    list->out("Nikita");
 
    delete list;
 
 
    /*
    customers* a = new customers("Vasya Pupkin");
    customers* b = new customers("Nikita Kozgemyka", "+7(978)897-54-65", "pos. Kurortnoe, ul. Nikitinoy 30");
    a->AddDebt("18.12.1992", 19.44);
    a->AddDebt("12.02.1994", 49.37);
    a->AddDebt("01.09.1996", 158.12);
    a->AddDebt("08.11.1997", -75.65);
    a->AddDebt("07.03.1998", 28.58);
 
    cout << a->GetName() << endl;
    cout << a->GetLastDate() << "\t" << a->GetFullDebt() << endl;
    a->out();
    cout << endl;
    b->AddDebt("08.11.1997", -425.65);
    cout << b->GetName() << "\t" << b->GetPhone() << "\t" << b->GetAdress() << endl;
 
    cout << b->GetLastDate() << "\t" << b->GetFullDebt() << endl;
 
    delete a;
    delete b;
    */
}
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.08.2019, 23:22
Ответы с готовыми решениями:

MSDN журнал. Подписка на бумажный журнал
Как подписаться на бумажный журнал или его в бумажном варианте по РФ не подписывают уже?

Журнал и процедура записи в журнал
есть таблица create table Debug_Log( id number, LogTime date, Message varchar(1024),...

Видеоуроки простого интернет-магазина на Node js на www.youtube.com? Или код интернет магазина с GitHub c коментами?
Искал видеоуроки по написанию сайта на node js, с толкового нашел только видеуроки Алексея Лущенко:...

Приложение Магазина "Покупки из приложения магазина", Моя Библиотека Windows
Всем привет, у меня пара вопросов про Магазин в Windows 10: 1. В Магазине есть приложение под...

2
221 / 148 / 79
Регистрация: 14.03.2016
Сообщений: 459
30.08.2019, 00:24 2
Лучший ответ Сообщение было отмечено AleksNos как решение

Решение

Не совсем понятно, зачем вы везде используете указатели. Предполагаю, вы работали на C#. Плюсы и шарп несколько отличаются работой с объектами. В плюсах не обязательно использовать конструкцию vector<history>* his = new vector<history>;, достаточно просто создать объект.

Собственно, именно в таком подходе и кроется ошибка. Когда вы вызываете метод addCustomer, то внутри создается временный объект, и так как при выходе из метода он будет уничтожен, память, выделенная на поле his, будет освобождена вашим деконструктором, однако из-за отсутствия кастомного конструктора копирования в классе customer, используется дефлотный, который просто копирует по типу поле-поле. Таким образом, тот объект, который лежит сейчас в векторе имеет указатель на уже освобожденный участок памяти, что при вызове декоструктора кинет исключение.
1
0 / 0 / 0
Регистрация: 26.07.2019
Сообщений: 9
30.08.2019, 08:51  [ТС] 3
Cortas, Не с С# не знаком, а с++ когда-то в университете преподавали и в голове одни указатели остались. Спасибо за замечание! Буду пробовать.

Добавлено через 29 минут
Cortas, Спасибо еще раз. Заработало!
Заменил в class customers
vector<history>* his; на vector<history> his;
Убрал his = new vector<history>; в конструкторе и delete his; в деструкторе.
И соответственно поправил конструкции типа this->his->at(i).date на this->his.at(i).date

Теперь буду пробовать с конструктором копирования.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.08.2019, 08:51

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Yii2 Шаблоны интернет-магазина / видеоуроки по созданию интернет-магазина
Доброго времени суток! Недавно начал изучать Yii2-framework. Точнее ище в том году начал, но...

Помогите написать БД для маленького магазина, нужно написать БД для магазина
Хелп. Задали написать лабораторную. Задание: написать БД для небольшого магазина в котором...

Журнал..
Захожу сёдня в нигаз, там есть стойка с журналами.. И тут мой взгляд привлекает некий журнал, на...

Журнал посещаемости
Всем привет! Нужна помощь в создании журнала посещаемости в Excel с автоматическим подсчётом...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.