string, класс, структуры C++
Всем привет!
Помогите, пожалуйста, найти ошибку в коде. Прошу прощения заранее, если мой вопрос кажется вам глупым, я только изучаю с++ и никак не могу понять, что делаю не так.
Я писала лабораторную для института, суть: создать базу данных на основе структуры, а также управлять этими структурами, используя методы класса. Вывод на экран разных сообщений обязательно должен быть где-то вне класса (в классе не может быть cin, cout).
С проблемой я столкнулась уже в процессе создания базы данных (поэтому других функций пока нет). Я могу ввести название экзамена, и выполнение программы останавливается, хотя по задумке она должна попросить ввести еще дату, фамилию (и так всего 3 раза, т.е. мы должны заполнить 3 структуры, потому что введенный размер базы данных = 3).
Вот код:
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
void Message (int, int);
int EnterSize();
void AllFunctions();
int EnterNumberOfFunction();
string EnterExamName();
string EnterExamDate();
string EnterProfessorLastName();
struct myStructure
{
string ExamName;
string ExamDate;
string ProfessorLastname;
bool isEmpty = true;
};
class Database {
private:
int dataBaseSize;
myStructure* dataBase;
public:
void DoFunction(int answer) {
bool cycle = true;
do {
switch(answer) {
case 0:
NewDataBase();
break;
default:
cycle = false;
break;
}
} while (cycle == true);
}
void NewDataBase () {
Message(0,0);
int index = 0;
dataBaseSize = EnterSize();
do {
dataBase[index].ExamName = EnterExamName();
dataBase[index].ExamDate = EnterExamDate();
dataBase[index].ProfessorLastname = EnterProfessorLastName();
Message(3,index);
index++;
} while (index < dataBaseSize);
}
};
int main() {
SetConsoleCP(65001);
SetConsoleOutputCP(65001);
Database newData;
AllFunctions();
newData.DoFunction(EnterNumberOfFunction());
return 0;
}
void Message (int answer, int index) {
switch(answer) {
case 0:
cout << "\nСоздание базы данных\n";
break;
case 3:
cout << "\nСтруктурная переменная №" << index+1 << " успешно добавлена!\n";
break;
}
}
int EnterSize() {
int size;
cout << "Введите размер базы данных: ";
cin >> size;
return size;
}
void AllFunctions() {
cout <<
"\nДоступные функции:\n"
"0. Создание базы данных\n"
"\n...\n";
}
int EnterNumberOfFunction() {
int answer;
cout << endl << "ВВЕДИТЕ НОМЕР ФУНКЦИИ: ";
cin >> answer;
return answer;
}
string EnterExamName() {
string ExamName;
cout << "Введите название экзамена: ";
cin >> ExamName;
return ExamName;
}
string EnterExamDate() {
string ExamDate;
cout << "Введите дату экзамена: ";
cin >> ExamDate;
return ExamDate;
}
string EnterProfessorLastName() {
string ProfessorLastname;
cout << "Введите фамилию преподавателя: ";
cin >> ProfessorLastname;
return ProfessorLastname;
}
Может быть, это какая-то проблема со string?
(если есть замечания по поводу стиля, логичности\нелогичности, с радостью выслушаю!)
Благодарю за внимание!
Ответы (2 шт):
В строке myStructure* dataBase; вы определили указатель, но не сказали куда ему ссылаться. Далее в методе NewDataBase вы обращаетесь к элементу массива: dataBase[index].ExamName = EnterExamName(); , а так как указатель ссылается "в никуда" - при выполнении этого участка получаете ошибку.
Чтобы этого избежать необходимо предварительно выделить память:
...
dataBaseSize = EnterSize();
dataBase = new myStructure[dataBaseSize];
...
Так как память выделяется вами, вами же она и должна быть возвращена, для этого необходимо добавить delete[] dataBase; в нужном вам месте, учитывая вашу архитектуру приложения - лучше всего в деструкторе класса. Хотя архитектуру приложения тоже лучше пересмотреть.
P.S. ваши циклы do...while лучше заменить на обычные while (в первом случае) и for (во втором).
Во-первых у тебя myStructure* dataBase; - это один элемент. Тебе его надо заменить на массив элементов, например на myStructure* dataBase[3];
Во-вторых у тебя очень запутанная структура программы. Зачем делать ввод данных через newData.DoFunction(EnterNumberOfFunction()); Такую структуру программы очень сложно отлаживать. Можно было сделать отдельный цикл, в котором вызывать метод добавления каждой записи. Например что-то вроде:
int answer = EnterNumberOfFunction();
do {
switch(answer) {
case 0:
newData.NewDataBase();
break;
case 1:
newData.NextFunction();
break;
default: // Условие выхода из цикла
cycle = false;
break;
}
} while (cycle == true);
В-третьих cin >> со строками может ожидать ввода бесконечного многострочного текста. Надо заменить на получение 1й строки от пользователя. Не помню, как в C++ это делается.
