Курсовая работа. Федеральное государственное автономное образовательное учреждение высшего образования
Скачать 243.5 Kb.
|
1 2 МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ
«Санкт-Петербургский государственный университет аэрокосмического приборостроения» КАФЕДРА ВЫЧИСЛИТЕЛЬНЫХ СИСТЕМ И СЕТЕЙ КУРСОВАЯ РАБОТА ЗАЩИЩЕНА С ОЦЕНКОЙ РУКОВОДИТЕЛЬ
РАБОТУ ВЫПОЛНИЛ
Санкт-Петербург 2018
Задачей курсового проекта является разработка информационной системы для заданной предметной области с использованием заданных структур данных. Создать базу данных, которая позволяет вводить информацию, хранить её в файле, осуществлять поиск, модификацию, сортировку и удаление данных. Тип хранимой информации и задание на поиск определяются в соответствии с номером варианта Вариант 1Описать структуру с именем ZNAK, содержащую следующие поля:
Задание на поиск: найти информацию о людях, чья фамилия введена с клавиатуры.
Данные о людях хранятся в структуре ZNAK struct ZNAK{ string firstName, lastName ; // имя и фамилия string znak; // знак зодиака int number[3]; // дата рождения }; struct List { ZNAK data; // поле информации структуры ZNAK List *next; // указатель на следующий элемент структуры }; База данных хранится на диске в виде текстового файла, файл находится в одной папке с консольным приложением и называется – ZNAK.txt. Для работы с БД в процессе выполнения программы используется динамическая структура данных. Информация будет храниться в виде односвязного списка. Пользователю будет доступно меню, пункты в котором соответствуют определенным действиям: 0 – Продолжить работу 1 – Добавление записи 2 – Редактирование 3 – Сортировка 4 – Удаление 5 – Сохранить 6 – Поиск 7 – Вывод на экран
string znak_init(List a) Данная функция заполняет поле - знак зодиака, на основании даты рождения человека. Входные данные: a – данные о человеке (List). Выходные данные: знак зодиака (string) void PLAN() Функция выводит на экран меню с действиями, доступными пользователю. Входные данные: - Выходные данные: - void print_table(List *begin) Функция выводит на экран данные о людях, находящихся в БД. Входные данные: begin – указатель на начало односвязного списка (List). Выходные данные: - void addList(List **begin,List **end, List a) Функция добавляет человека в список. Входные данные: begin – указатель на начало односвязного списка (List). end – указатель на конец односвязного списка (List). a – данные о человеке (List). Выходные данные: - bool checkNumbersInString(string str) Функция проверяет наличие цифр в строке. Входные данные: str – строка (string) Выходные данные: Значение, уведомляющее нас о наличии цифры в строке - 1, или говорящее о её отсутствии – 0. int size_table(List *begin) Эта функция подсчитывает количество человек, находящихся в БД. Входные данные: begin – указатель на начало списка (List). Выходные данные: количество человек в ДБ (int). long long int birthDay(int *b) Функция подсчитывает сколько дней от 0 до дня рождения человека. Это нужно для того, чтобы определить кто старше, позже эта функция используется в сортировке. Входные данные: b – массив из трех чисел, которые представляют собой дату рождения (int). Выходные данные: Число, характеризующее возраст (long long int). void Free(List **begin) Функция освобождает динамически выделенную память. Входные данные: begin – указатель на начало односвязного списка (List). Выходные данные: - void delist(List **begin,List a) Функция удаляет человека из БД. Входные данные: begin – указатель на начало односвязного списка (List). a – данные о человеке (List). Выходные данные: - bool space_in_string(string a) Функция проверяет наличие пробела в строке. Входные данные: a – имя/фамилия (string). Выходные данные: Значение, говорящее от наличии пробела в строке – 0, его отсутствие -1. List inputValueСheck() Функция предназначена для ввода данных о человеке. Входные данные: - Выходные данные: Информация о человеке, удовлетворяющая определенным условиям. (List) List* search(List *begin, List a) Функция ищет человека в списке. Входные данные: begin – указатель на начало односвязного списка (List). a – данные о человеке (List). Выходные данные: Адрес элемента списка (List). void search3(List *begin) Функция выводит на экран информацию о людях, фамилия которого была введена. Если фамилий несколько, то выводит на экран все фамилии. Входные данные: begin – указатель на начало односвязного списка (List). Выходные данные: - void edit(List *begin,List *q) Функция редактирует имя/фамилию/дату рождения человека Входные данные: begin – указатель на начало односвязного списка (List). q – данные о человеке, которые хотите изменить (List). Выходные данные: - void sort_table(List *begin) Функция сортирует данные людей в алфавитном порядке. Входные данные: begin – указатель на начало односвязного списка (List). Выходные данные: - void save_data(List *begin) Функция сохраняет БД в текстовый файл. Входные данные: begin – указатель на начало односвязного списка (List). Выходные данные: - void continue_work(List **begin, List **end) Функция читает данные из текстового документа, тем самым позволяя продолжить работу. Входные данные: begin – указатель на начало односвязного списка (List). end – указатель на конец односвязного списка (List). Выходные данные: - void allarmToSave(List *begin) При выходе из программы, функция предлагает нам сохраниться. Входные данные: begin – указатель на начало односвязного списка (List). Выходные данные: - List input_UPD(List *begin) Улучшенный ввод данных. Применяется в поиске/редактировании/удалении для того, чтобы не вводить полную информацию о человеке. Входные данные: begin – указатель на начало односвязного списка (List). Выходные данные: обработанная информация о человеке (List)
При запуске программы открывается консольное приложение (Рис.1): Рис.1 При нажатии цифры – 0, программа считает данные из файла, если тот не пуст (Рис.2 а). Рис.2 а В случае отсутствия данных, программа выведет специальное сообщение от этом (Рис.2 б). Рис.2 б Посмотрим, что мы загрузили из файла (Рис.3): Рис.3 Добавим запись и посмотрим на новый список (команда 1, затем 7), (Рис.4) При добавлении записи происходит ряд проверок, таких как: наличие пробелов или цифр в строке, год в промежутке от 1950-2000, месяц от 1-12, учитывается количество дней, соответствующих данному месяцу и году. Также осуществляется проверка на наличие уже записанных данных о человеке в БД, если такие данные имеются, вас попросят ввести другие данные. Рис.4 Выбрав пункт 2- редактирование, вы должны ввести имя человека, которого хотите редактировать. Если с таким именем больше одного человека, то вам предложат ввести фамилию, если опять будут совпадения, то в должны будете ввести дату рождения. Подразумевается по условию, что двух людей с одинаковыми данными в таблице быть не может. В функции также происходят проверки на ввод данных ( Рис.5) Рис.5 Пункт 3 - сортирует данные в алфавитном порядке методом пузырька. Если находят два человека с одинаковыми именами и фамилиями, то выше в списке будет тот, кто младше. При всем этом осуществляются проверки на ввод (команда 3, затем 7), (Рис.6) Рис.6 Выбирая пункт 4 – удаление, вам предложат ввести данные о человеке, которого надо удалить из списка. Если мы передумали, то можно нажать цифру 0, и мы выйдем из этой функции. Также осуществляются проверки на ввод данных (Рис.7) Рис.7 При нажатии клавиши 5 – происходит сохранение списка в текстовый файл (Рис.8) Рис.8 Поиск осуществляется по фамилии. По ней нам выводится список людей с такой фамилией, удовлетворяющей условию поиска (Рис.9) Рис.9 Вывод списка можно увидеть на рисунках выше. И напоследок, при выходе из программы, нам предоставляется выбор: сохранить текущую информацию, или нет. (Рис.10) Рис.10
В ходе курсовой работы был успешно разработан алгоритм, представляющий информационную систему, в которую можно добавлять информацию, хранить её в файле, осуществлять поиск, модификацию, сортировку и удаление данных. Из достоинств программы хочу отметить хорошую проверку вводимых значений, пользователь не сможет вывести из строя программу, также в ней удобный и понятный интерфейс. Из недостатков можно упомянуть: ограничение на ввод пробелов в имени/фамилии, алгоритм не очень хорошо оптимизирован, также, если мы решим сами написать в файл данные о людях, и мы заполним этот файл не по определенным правилам, то данные считаются неправильно – будет ошибка, и так можно продолжать долго, ведь совершенству нет предела. Просуммировав все достоинства и недостатки можно говорить об успешной реализации поставленной задачи. 6. Листинг программы #include #include #include #include using namespace std; struct ZNAK { string firstName, secondName, znak; int number[3]; }; struct List { ZNAK data; List *next; }; string znak_init(List a) { int year365_6[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (a.data.number[2] % 4 == 0 && a.data.number[2] % 400 == 0) { year365_6[1] = 29; } string temp; int days = 0; days = a.data.number[0] + a.data.number[1] * year365_6[a.data.number[1]-1]; if (days >= 114 && days <= 140) temp = "Овен"; else if (days >= 141 && days <= 175) temp = "Телец"; else if (days >= 176 && days <= 201) temp = "Близнецы"; else if (days >= 202 && days <= 239) temp = "Рак"; else if (days >= 240 && days <= 271) temp = "Лев"; else if (days >= 272 && days <= 293) temp = "Дева"; else if (days >= 294 && days <= 333) temp = "Весы"; else if (days >= 334 && days <= 352) temp = "Скорпион"; else if (days >= 353 && days <= 393) temp = "Стрелец"; else if (days >=394 && days <=403 || days >=32 && days <=51) temp = "Козерог"; else if (days >= 52 && days <= 76) temp = "Водолей"; else if (days >= 77 && days <= 113) temp = "Рыбы"; return temp; } void PLAN() { cout << "0. Продолжить работу\n" << "1. Добавление записи\n" << "2. Редактирование\n" << "3. Сортировка\n" << "4. Удаление\n" << "5. Сохранить\n" << "6. Поиск\n" << "7. Вывод на экран\n" << "8. Выход\n"; } void print_table(List *begin) { if (begin == NULL) { cout << "Список пуст!\n" << endl; return; } List *a = begin; int i = 1; while (a) { cout << i << ") " << a->data.firstName << " " << a->data.secondName << " " << a->data.number[0] << "." << a->data.number[1] << "." << a->data.number[2] << " " << a->data.znak << endl; a = a->next; i++; } cout << "\n::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" << endl; } void addList(List **begin,List **end, List a) { static bool x = true; if (*begin == NULL) x = true; if (x) { *begin = new List; (*begin)->data = a.data; (*begin)->next = NULL; *end = *begin; x = false; return; } (*end)->next = new List; *end = (*end)->next; (*end)->data = a.data; (*end)->next = NULL; } bool checkNumbersInString(string str) { for (int i = 0; i < str.length(); i++) { if (static_cast return true; } return false; } int size_table(List *begin) { List *temp = begin; int i = 0; while (temp) { ++i; temp = temp->next; } return i; } long long int birthDay(int *b) { long long int p = 0; p = b[0] + b[1] * 30 + b[2] * 360; return p; } void Free(List **begin) { if (*begin == 0) return; List *p = *begin; List *t; while (p) { t = p; p = p->next; delete t; } *begin = NULL; } void delist(List **begin,List a) { List *temp = *begin; if (*begin == NULL) { cout << "Список пуст!\n" << endl; return; } if (temp->data.firstName == a.data.firstName && temp->data.secondName == a.data.secondName && temp->data.number[0] == a.data.number[0] && temp->data.number[1] == a.data.number[1] && temp->data.number[2] == a.data.number[2]) { *begin = (*begin)->next; delete temp; cout << "Элемент " << a.data.firstName << " " << a.data.secondName << " " << a.data.number[0] << "." << a.data.number[1] << "." << a.data.number[2] << " удален!" << endl; return; } List *t1 = temp->next; bool flag = true; while (t1) { if (t1->data.firstName == a.data.firstName && t1->data.secondName == a.data.secondName && t1->data.number[0] == a.data.number[0] && t1->data.number[1] == a.data.number[1] && t1->data.number[2] == a.data.number[2]) { temp->next = t1->next; delete t1; flag = false; cout << "Элемент " << a.data.firstName << " " << a.data.secondName << " " << a.data.number[0] << "." << a.data.number[1] << "." << a.data.number[2] << " удален!" << endl; return; } temp = t1; t1 = t1->next; } if (flag) cout << "Данного человека нет в списке!\n" << endl; } bool space_in_string(string a) { short s = 0; for (int i(0); i < a.length(); i++) { if (a[i] == ' ') s++; } if (s == 0) return false; else return true; } List inputValueСheck() { List a; cout << "Введите имя: "; getline(cin, a.data.firstName); while (1) { if (space_in_string(a.data.firstName)) { cout << "В имени присутствует пробел. Повторите: "; cin.clear(); cin.sync(); getline(cin, a.data.firstName); } else if (checkNumbersInString(a.data.firstName)) { cout << "В имени присутствуют цифры. Повторите: "; cin.clear(); cin.sync(); getline(cin, a.data.firstName); } else break; } cout << "Введите фамилию: "; getline(cin, a.data.secondName); while (1) { if (space_in_string(a.data.secondName)) { cout << "В фамилии присутствует пробел. Повторите: "; cin.clear(); cin.sync(); getline(cin, a.data.secondName); } else if (checkNumbersInString(a.data.secondName)) { cout << "В фамилии присутствуют цифры. Повторите: "; cin.clear(); cin.sync(); getline(cin, a.data.secondName); } else break; } cout << "Введите дату рождения (год): "; int temp[3]; while (!(cin >> temp[2] && temp[2] >= 1950 && temp[2] <= 2000)) { cin.clear(); cin.sync(); cout << "Возможно, вы ввели букву, либо ввели число не в промежутке от 1950 до 2000. Повторите: "; } cout << "Введите дату рождения (месяц): "; while (!(cin >> temp[1] && temp[1] >= 1 && temp[1] <= 12)) { cin.clear(); cin.sync(); cout << "Возможно, вы ввели букву, либо ввели число не в промежутке от 1 до 12. Повторите: "; } cout << "Введите дату рождения (день): "; int year365_6[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (temp[2] % 4 == 0 && temp[2] % 400 == 0) { year365_6[1] = 29; } while (!(cin >> temp[0] && temp[0] >= 1 && temp[0] <= year365_6[temp[1] - 1])) { cin.clear(); cin.sync(); cout << "Возможно, вы ввели букву, либо ввели число не в промежутке от 1 до "< } for (int i = 0; i < 3; i++) a.data.number[i] = temp[i]; a.data.znak = znak_init(a); cin.get(); return a; } List* search(List *begin, List a) { bool flag = true; List *temp = begin; if (begin == NULL) { cout << "В таблице нет элементов!\n" << endl; return 0; } else { while (temp) { if (temp->data.firstName == a.data.firstName && temp->data.secondName == a.data.secondName && temp->data.number[0] == a.data.number[0] && temp->data.number[1] == a.data.number[1] && temp->data.number[2] == a.data.number[2]) { flag = false; break; } temp = temp->next; } if (!flag) { cout << "Человек найден!\n" << endl; return temp; } else { cout << "Данного человека нет в базе!\n" << endl; return 0; } } cout << endl; } void search3(List *begin) { List *temp = begin, a; do{ print_table(begin); int s = 0; cout << "Введите фамилию:/назад - 0 "; getline(cin, a.data.secondName); while (1) { if (a.data.firstName[0] == ' ') { cout << "Первый символ в фамилии пробел. Повторите: "; getline(cin, a.data.firstName); } else if (a.data.secondName == "0") { cout << "Действие отменено!" << endl; return; } else if (checkNumbersInString(a.data.secondName)) { cout << "В фамилии присутствуют цифры. Повторите: "; getline(cin, a.data.secondName); } else break; } for (int i = 0; i < size_table(begin); i++) { if (a.data.secondName == temp->data.secondName) s++; temp = temp->next; } temp = begin; if (s == 0) { system("cls"); cout << "Нет совпадений фамилии. Повторите:\n" << endl; } else break; } while (1); system("cls"); short qq = 1; for (int i = 0; i < size_table(begin); i++) { if (a.data.secondName == temp->data.secondName) { cout << qq << ") " << temp->data.firstName << " " << temp->data.secondName << " " << temp->data.number[0] << "." << temp->data.number[1] << "." << temp->data.number[2] << " " << temp->data.znak << endl; qq++; } temp = temp->next; } cout << endl; } void edit(List *begin,List *q) { List _q = *q; if (begin == NULL) { cout << "Таблица пуста!\n" << endl; return; } char c; do { system("cls"); cout << q->data.firstName << " " << q->data.secondName << " " << q->data.number[0] << "." << q->data.number[1] << "." << q->data.number[2] << endl; cout << "Что вы хотите изменить:\n1. Имя\n2. Фамилию\n3. Дату рождения\n0. Выход" << endl; cout << "Выберите значение: "; cin >> c; switch (c) { case '1': { cin.sync(); cout << "Введите новое имя: "; while (1) { getline(cin, _q.data.firstName); if (checkNumbersInString(_q.data.firstName)) { cout << "В имени присутствуют цифры. Повторите: "; getline(cin, _q.data.firstName); } if (search(begin, _q)) { cout << "Человек с идентичными данными уже есть, введите другое имя: "; } else break; } break; } case '2': { cin.sync(); cout << "Введите новую фамилию: "; while (1) { getline(cin, _q.data.secondName); if (checkNumbersInString(_q.data.secondName)) { cout << "В фамилии присутствуют цифры. Повторите: "; getline(cin, _q.data.secondName); } if (search(begin, _q)) { cout << "Человек с идентичными данными уже есть, введите другую фамилию: "; } else break; } break; } case '3': { do { cin.sync(); cout << "Введите дату рождения (год): "; int temp[3]; while (!(cin >> temp[2] && temp[2] >= 1950 && temp[2] <= 2000)) { cin.clear(); cin.sync(); cout << "Возможно, вы ввели букву, либо ввели число не в промежутке от 1950 до 2000. Повторите: "; } cout << "Введите дату рождения (месяц): "; while (!(cin >> temp[1] && temp[1] >= 1 && temp[1] <= 12)) { cin.clear(); cin.sync(); cout << "Возможно, вы ввели букву, либо ввели число не в промежутке от 1 до 12. Повторите: "; } cout << "Введите дату рождения (день): "; int year365_6[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; if (temp[2] % 4 == 0 && temp[2] % 400 == 0) { year365_6[1] = 29; } while (!(cin >> temp[0] && temp[0] >= 1 && temp[0] <= year365_6[temp[1] - 1])) { cin.clear(); cin.sync(); cout << "Возможно, вы ввели букву, либо ввели число не в промежутке от 1 до " << year365_6[temp[1] - 1] << ". Повторите: "; } for (int i = 0; i < 3; i++) _q.data.number[i] = temp[i]; if (search(begin, _q)) { cout << "Человек с идентичными данными уже есть, введите другую дату рождения: " << endl; } else break; } while (1); break; } } *q = _q; } while (c != '0'); cin.get(); cout << endl; } void sort_table(List *begin) { List *a = begin; List *buf = new List[size_table(begin)]; for (int i = 0; i < size_table(begin); i++) { buf[i] = *a; a = a->next; } for (int i = 0; i < size_table(begin); i++) { for (int j = 0; j < size_table(begin); j++) { if (buf[i].data.firstName < buf[j].data.firstName) { swap(buf[i].data.secondName, buf[j].data.secondName); swap(buf[i].data.firstName, buf[j].data.firstName); swap(buf[i].data.number[0], buf[j].data.number[0]); swap(buf[i].data.number[1], buf[j].data.number[1]); swap(buf[i].data.number[2], buf[j].data.number[2]); swap(buf[i].data.znak, buf[j].data.znak); } else if (buf[i].data.firstName == buf[j].data.firstName) { if (buf[i].data.secondName < buf[j].data.secondName) { swap(buf[i].data.secondName, buf[j].data.secondName); swap(buf[i].data.firstName, buf[j].data.firstName); swap(buf[i].data.number[0], buf[j].data.number[0]); swap(buf[i].data.number[1], buf[j].data.number[1]); swap(buf[i].data.number[2], buf[j].data.number[2]); swap(buf[i].data.znak, buf[j].data.znak); } else if (buf[i].data.secondName == buf[j].data.secondName) { if (birthDay(buf[i].data.number) < birthDay(buf[j].data.number)) { swap(buf[i].data.secondName, buf[j].data.secondName); swap(buf[i].data.firstName, buf[j].data.firstName); swap(buf[i].data.number[0], buf[j].data.number[0]); swap(buf[i].data.number[1], buf[j].data.number[1]); swap(buf[i].data.number[2], buf[j].data.number[2]); swap(buf[i].data.znak, buf[j].data.znak); } } } 1 2 |