Титульный лист Задание 2 СОДЕРЖАНИЕ Введение ................................................................................................................... 4 1 Синтаксис объявления класса. Режимы доступа к элементам класса ............ 5 2 Анализ и разработка программного обеспечения ............................................ 7 2.1 Анализ предметной области и формулирование функциональных требований ........................................................................................................... 7 2.2 Разработка структуры программы и алгоритмов работы модулей программы............................................................................................................ 8 2.3 Описание программного кода .................................................................... 12 3 Демонстрация работы ........................................................................................ 15 3.1 Руководство пользователя .......................................................................... 15 3.2 Тестирование программы ........................................................................... 23 Заключение ............................................................................................................ 26 Список использованных источников .................................................................. 27 Приложение А Блок-схемы алгоритмов ............................................................. 28 Приложение Б Листинг программного кода ...................................................... 30 Приложение В Презентация разработанного ПО .............................................. 51 3 ВВЕДЕНИЕ ООП — подход к программированию как к моделированию информационных объектов, решающий на новом уровне основную задачу структурного программирования: структурирование информации с точки зрения управляемости, что существенно улучшает управляемость самим процессом моделирования, что, в свою очередь, особенно важно при реализации крупных проектов[1]. Объектная ориентированность C++ означает, что он поддерживает стиль программирования, упрощающий кодирование крупномасштабных программ и обеспечивающий их расширяемость. C++ представляет собой объектноориентированный низкоуровневый язык программирования, отвечающий стандартам ANSI и Международной организации стандартов ISO. C++ может генерировать эффективные высокоскоростные программы. Сертификация ANSI и ISO обеспечила переносимость C++: написанные на нем программы совместимы с большинством современных сред программирования [2]. Целью данной курсовой работы является разработка алгоритма программы учета переговоров абонентов сотовой связи. Оператор сотовой связи хранит информацию о разговорах своих абонентов: номер абонента; ФИО абонента; указание принадлежности вызова к исходящему или входящему; номер исходящего или входящего вызова; дата звонка; время звонка; продолжительность разговора; тариф одной минуты. Вывести по каждому абоненту за требуемый период времени: перечень входящих и исходящих вызовов, общее время входящих вызовов, общее время исходящих вызовов, общую сумму на исходящие вызовы (требуемый период времени вводится с клавиатуры) [2]. На уровне конструирования освоены технологии нисходящего проектирования и принципов методологии структурного программирования. Результат этапа конструирования представляется в форме графических блоксхем алгоритмов. На уровне программирования реализованы графические блок-схемы алгоритмов на языке С++. Результат этапа программирования представляется в форме проекта в среде разработки приложений на языке С++ Microsoft Visual Studio. В программе используются функции, которые предназначены, в первую очередь, для сокращения объема исходного кода. В частности, в работе рассмотрен диалог с пользователем, а также представлены результаты тестирования программы. 4 1 СИНТАКСИС ОБЪЯВЛЕНИЯ КЛАССА. РЕЖИМЫ ДОСТУПА К ЭЛЕМЕНТАМ КЛАССА В С++ классы и структуры тесно взаимосвязаны. Фактически, за одним исключением, они взаимозаменяемы, по-скольку структура в С++ может включать как данные, так и код, который может манипулировать этими данными таким же образом, как и класс. Структуры также могут содержать конструкторы и деструкторы. Единственное отличие между ними связано с тем, что по умолчанию члены класса имеют в качестве спецификатора доступа private, тогда как спецификатором доступа членов струк-туры служит public. Согласно формальному синтаксису С++, ключевое слово struct определяет тип класса [3]. В большинстве случаев на языке С++ используют классы для определения объектов, содержащих и данные и код. Они используют структуры для определения объек-тов, содержащих только данные. Это означает, что структуры используются обычно точно в том же стиле, что и структуры в языке С. Тем не менее время от времени встречается код на языке С++, который использует расширенные возможности структур [3]. Точно так же, как структуры и классы связаны между собой, связаны и объединения и классы. Объединения представляют по существу структуру, в которой все элементы хранятся в одном и том же месте. Объединения могут содержать конструкторы и деструкторы, а также функциичлены и дружественные функции. Подобно структурам, члены объединения по умолчанию имеют в качестве спецификатора доступа public. Так, следующая программа использует объединение для вывода символов, соответствующих старшему и младшему байтам короткого целого (имеющего размер в два байта как для 16-битных, так и для 32-битных сред): #include <iostream.h> union u_type { u_type(short int a); // по умолчанию публичные void showchars (); short int i; char ch[2]; }; // конструктор u_type::u_type(short int a) { i = a; } // показ символов, которые содержит short int. void u_type::showchars() cout << ch [ 0 ] << " "; cout << ch [ 1 ] << "\n"; 5 int main() u_type u(1000); u.showchars (); return 0; } Важно понимать, что подобно структуре, объявление объединения определяет тип класса. Это означает, что принципы инкапсуляции сохраняют свою силу[3] . Имеется несколько ограничений, которые необходимо иметь в виду при использовании объе-динений в С++. Первое — объединение не может наследовать какие-либо другие классы. Далее объединение не может использоваться в качестве базового класса. Объединение не может иметь виртуальные функции-члены. Никакие статические переменные не могут быть членами объединения. Объединение не может иметь в качестве члена какой-либо объект, перегружающий оператор =. Никакой объект не может быть членом объединения, если этот объект имеет конструктор или деструктор [3]. 6 2 АНАЛИЗ И РАЗРАБОТКА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ 2.1 Анализ предметной области и формулирование функциональных требований Исходные данные к курсовой работе: 1 Индивидуальное задание выбирается из списка, приведенного в данном файле. 2 Язык программирования С++. 3 Рекомендуемая среда разработки Microsoft VisualStudio. 4 Вид приложения – объектно-ориентированное консольное. 5 Хранение данных в памяти должно быть организовано посредством классов (объектно-ориентированная база данных). 6 Физически данные должны храниться в файлах. При запуске программы происходит загрузка данных из файла в массив, либо другую структуру данных (допускается использование стандартный контейнеров библиотеки STL – vector, list), компонентами которой являются объекты. Перед завершением работы программы, либо при выборе соответствующего пункта меню происходит сохранение данных в текстовый файл (перезапись исходного файла данных). 7 Построение программного кода должно соответствовать правилам, определенным в документе «С++ CodeConvention». 8 Текст пояснительной записки оформляется в соответствии со стандартом предприятия СТП 01–2017. В задании на курсовую работу необходимо создать программу учета переговоров абонентов сотовой связи. Оператор сотовой связи хранит информацию о разговорах своих абонентов: номер абонента; ФИО абонента; указание принадлежности вызова к исходящему или входящему; номер исходящего или входящего вызова; дата звонка; время звонка; продолжительность разговора; тариф одной минуты. Вывести по каждому абоненту за требуемый период времени: перечень входящих и исходящих вызовов, общее время входящих вызовов, общее время исходящих вызовов, общую сумму на исходящие вызовы (требуемый период времени вводится с клавиатуры). Общее для всех вариантов задание: реализовать авторизацию для входа в систему (без регистрации!), функционал администратора и функционал пользователя, как минимум три вида поиска, как минимум три вида сортировки. 7 2.2 Разработка структуры программы и алгоритмов работы модулей программы Структуры, модули и алгоритмы позволяют понять и определить функции программы, а дальнейшая детализация даст возможность обнаружить ошибки и не достающие функции. Программный модуль - это отдельная часть программного кода, фрагмент программы, который полностью самостоятельно выполняет свою задачу, оформленный в виде отдельного файла с исходным кодом или поименованной непрерывной еѐ части. Эти модули предназначаются для использования в других программах или же для расширения возможностей как, например, библиотека плагинов. Разбиение всей программы на отдельные модули позволяет решение общей, сложной задачи разделить на решение нескольких, более простых. Что в свою очередь увеличивает скорость и качество разработки, когда каждый занимается своим модулем программы, а затем их собирают в единый проект. В общем случае модули проектируются таким образом, чтобы предоставлять программистам удобную для многократного использования функциональность (интерфейс) в виде набора функций, классов, констант. Модули можно объединять в пакеты, а несколько пакетов можно объединять в библиотеки. Возможность изменения или обновления одного модуля не затрагивая всей программы и остальных модулей является главным удобством использования модульной архитектуры. Также разделение программы на модули позволяет распределить нагрузку, в случае большой потребности ПО в ресурсах, при запуске разных модулей на разных серверах, используя так называемую распределенную архитектуру. Модульное программирование подразумевает разбивание всей программы на различные функциональные блоки, которые называют модулями. Каждый модуль имеет свое назначение, определенный размер, а также определенный интерфейс работы с другими модулями. Можно, конечно, использовать монолитный способ написания программы, но, в случае написания больших проектов, этот способ является совершенно неприемлемым. Главным вопросом в использовании модульной архитектуры является принцип разделения программы на модули [4]. В объектно-ориентированном программировании основная задача методов заключается в том, чтобы изменять текущее состояние объекта, но до тех пор, когда в программе объекты ещѐ не используются, методы уже могут вводиться. Метод, который описан внутри некоторого класса, но вызывается без приложения к конкретному объекту этого класса, называется статическим. Выбор реализации методов класса в качестве статических обусловлен тем, что для доступа к нужной формуле из тела программы не придется создавать объект класса, реализующего данную формулу. К тому же у каждого класса большой объем реализованных математических моделей и формул расчета надежности и интенсивности отказов, поэтому создание такого объекта задействует сравнительно большой объем памяти, чего естественно необходимо избегать. А реализация всех методов реализации расчетов в 8 качестве статичных методов позволит избежать ненужной потери памяти и не обусловленного расхода ресурсов вычислительной системы. Структура данных программного обеспечения на рисунке ниже. Рисунок 2.1. Рисунок 2.1 – Структура программы Структурная организация является необходимой при планировании перемещения данных в программе, так же она выявляет необходимое количество сущностей и их атрибутов. Программный модуль структуры для абонента показан на рисунке 2.2: 9 Рисунок 2.2 – Структура для абонента Рисунок 2.3 – Программная структура пользователя Описание структур программным кодом: // структура (список) пользователей struct User { string name; //имя пользователя string pass; //пароль int role; // 0 - админ 1...-пользователь }; // структура (список) об абонентах struct Abonent { string nomer; //Номер абонента; string familia; //Фамилия; string imya; //Имя; string otchestvo; //Отчество; bool tip_vizova; //Тип вызова (0-входящий, 1-исходящий) string nomer_x; //Номер исходящего или входящего вызова string data_x; //Дата звонка; string vremya_x; //Время звонка; float dlitelnost; //Продолжительность разговора; float tarif; //Тариф одной минуты; }; 10 Алгоритм работы программы выглядит следующим образом: администратор обязан ввести свой логин и пароль, при успешном сопоставлении их со значениями, хранимыми в программе. После входа в зависимости от роли пользователя, выводится меню для администратора «admin» и пользователя «user» соответственно. В режиме работы администратора можно обеспечить ввод и редактирование информации. Доступны такие средства редактирования как: "Добавить" и "Удалить". Предусмотрена возможность сортировки данных по нескольким полям, а так же поиска информации. В режиме работы пользователя активна функция просмотра информации обо всех абонентах, возможно выполнять выбор. Информация после внесения изменений об абонентах обновляется. При добавлении либо изменении записей предусмотрено отображение маски ввода для исключения ошибок ввода. При изменении и удалении записей предусмотрена проверка на существование данной записи. Сортировка может осуществляться по выбранным полям, но все остальные значения этой строки сохраняются. Функционалом предусмотрена защита от ввода ошибочных значений. Если исходные данные будут введены неправильно, будет показана информация об ошибке и программа снова запросит их ввод. Программа позволяет отразить информацию об авторе с указанием атрибутов создателя. При разработке ПО учтена возможность возврата на предыдущее меню и выхода из любой части программы. Для сокращения объема исходного кода и для улучшения его читаемости используются функции. Они позволяют вынести часто повторяющиеся выражения в отдельный блок и затем, обращаться к нему. В программе будут созданы функции и показаны алгоритмы работы модулей программы. Алгоритмы работы ПО описаны следующими функциями: int authorization()- функция авторизации пользователя в системе. Возвращает значение роли 0-администратор 1-пользователь. Алгоритм функции авторизации показан на рисунке А.1 приложения А. Считываются данные из файла с учетными записями пользователей следующего вида: login; password; role. После ввода пользователем своих персональных данных и сверки со считанной из файла информацией предусмотрена возможность входа в качестве администратора или в качестве пользователя. void showUsers(User* arr_of_users, int number_of_users) - функция для отображения пользователей на экране. Функция для отображения пользователей на экране. Алгоритм функции показан на рисунке А.3 приложения А. void sortUsers(User* arr_of_users, int& number_of_users) - Функция отображения вариантов сортировки и сортировки записей. Выполняет упорядочивание абонентов в определенном порядке, учитывая их атрибуты. Алгоритм функции показан на рисунке А.4 приложения А. 11 2.3 Описание программного кода Программная реализация. Для качественного стиля программирования, тексты всех информационных сообщений, выводимых пользователю в ответ на его действия, также оформлены как константы. Код прокомментирован в части объявления структур, массивов/векторов, прототипов функций, нетривиальной логики. Код не дублируется – для исключения этого использованы функции. Одна функция решает только одну задачу. Внутри функции возможен вызов других функций. Выполнение операций чтения/записи в файл сведено к минимуму: после однократной выгрузки данных из файла в массив/вектор дальнейшая работа ведется с этим массивом/вектором, а не происходит многократное считывание данных из файла в каждой функции. Вложенность блоков не более трех. Исключены длинные функции. Вынесен код логически независимых модулей в отдельные .cpp файлы и подключены с помощью заголовочных .h файлов. Все переменные и константы имеют осмысленные имена. Переменным присвоены имена, состоящие из букв нижнего регистра; для формирования составного имени, используется нижнее подчеркивание. Имена функций ПО начинаются с буквы нижнего регистра, строится по принципу глагол+существительное. Код не содержит неименованных числовых констант, неименованных строковых констант. В программе реализованы следующие функции: // функция авторизации пользователя в системе. Возвращает значение роли 0администратор 1-пользователь int authorization(); Функции для отображения меню администратора // Функция стартового меню для администратора void adm_menu_start(); // Функция меню работы с пользователями для администратора void adm_menu_users(); // функция меню работы с абонентами для администратора void adm_menu_abonents(); // функция меню работы с абонентами для администратора //void adm_menu_abonents() Функции для отображения меню пользователя // Функция стартового меню для администратора void user_menu_start(); Функции для работы с пользователями 12 // Функция считывания пользователей из файла в массив памяти arr_of_users void readUsers(User* arr_of_users, int& number_of_users); // Функция для отображения пользователей на экране void showUsers(User* arr_of_users, int number_of_users); // Функция для добавления нового пользователя в массив + дозапись в конец файла void addUserInArray(User* arr_of_users, int& number_of_users); // функция изменения пользователя и перезаписи файла void editUser(User* arr_of_users, int number_of_users); // Функция удаления пользователя void dellUser(); // Функция для дозаписи нового пользователя в файл void writeEndFileUsers(User new_user); // Функция для перезаписи файла пользователей void writeFileUsers(User* arr_of_users, int number_of_users); // Функция сортировки пользователей по имени void sortUsers(User* arr_of_users, int& number_of_users); Функции общего назначения // Функция для получения кол-ва записей в файле (путь к файлу) int getCountOfStucturesInFile(string file_path); // Функция для удаления строки (имя файла, номер строки) bool remove_line(string file_path, size_t index); Функции для работы с данными по абонентами // Функция считывания списка вызовов из файла в массив памяти arr_of_abonents void readAbonents(Abonent* arr_of_abonents, int& number_of_abonents); // Функция для отображения списка вызовов на экране void showAbonents(Abonent* arr_of_abonents, int number_of_abonents); // Функция для добавления нового абонента в массив + дозапись в конец файла void addAbonentInArray(Abonent* arr_of_abonents, int& number_of_abonents); // Функция изменения абонента и перезаписи файла void editAbonent(Abonent* arr_of_abonents, int number_of_abonents); // Функция для перезаписи файла абонентов void writeFileAbonents(Abonent* arr_of_abonents, int number_of_abonents); // Функция для дозаписи нового абонента в файл void writeEndFileAbonents(Abonent new_abonent); // Функция удаления абонента void dellAbonent(); // Функция отображения вариантов сортировки и сортировки записей о абонентах 13 void sortAbonents(Abonent* arr_of_abonents, int& number_of_abonents); // Функция отображения вариантов сортировки и сортировки записей о абонентах void vivod_po_IZ(Abonent* arr_of_abonents, int& number_of_abonents); // Функция бронирования билетов эконом класса Полный код (листинг) программы показан в приложении Б. 14 3 ДЕМОНСТРАЦИЯ РАБОТЫ 3.1 Руководство пользователя Для начала работы с программой необходимо запустить программу (фйл.exe). Началом работы будет провнрка сопутствующих файлов проекта и авторизация, окно, представленное на рисунке 3.1. В рамках данного этапа считываются данные из файла с учетными записями пользователей следующего вида: login; password; role: данное поле служит для разделения в правах администраторов и пользователей. После ввода своих персональных данных (логина и пароля) и сверки со считанной из файла информацией необходимо предусмотрена возможность входа в качестве администратора или в качестве пользователя. Рисунок 3.1 – Процесс авторизации Данные хранятся в отдельном файле. После входа в систему появится стартовое меню администратора для работы. Для работы с данными предусмотрены два функциональных модуля: модуль администратора и модуль пользователя. Модуль администратора включает следующие подмодули (с указанием функциональных возможностей): управление учетными записями пользователей: просмотр всех учетных записей; добавление новой учетной записи; редактирование учетной записи; удаление учетной записи; работа с файлом данных: создание файла; открытие существующего файла; удаление файла; работа с данными: а) режим редактирования: просмотр всех данных; добавление новой записи; удаление записи; редактирование записи; б) режим обработки данных: выполнение задания; поиск данных. Программная часть индивидуальна, об уникальности работы свидетельствуют имена переменных, констант, функций; комментарии и др. Информация о создателе программного кода показана на рисунке 3.2. В содержании меню указаны инициалы исполнителя работы, учебная группа, руководитель работы. 15 Рисунок 3.2 – Информация о разработчике ПО Главное меню для администратора показано на рисунке 3.3. Оно содержит данные о работе с пользователями, работу с данными ЖД вокзала, возвращение к авторизации, выход из программы, информацию о программе. Путем выбора пункта меню, выполняем необходимый процесс обращения к программе. Рисунок 3.3 – Главное меню администратора Работа с пользователями. Функция позволяет выполнять добавление, изменение, удаление пользователя, навигацию по меню и выход из программы. Путем ввода нужного пункта меню, осуществляется обращение к программе. Меню работы с пользователями показаны на рисунке 3.4 Рисунок 3.4 – Работа с пользователями 16 Реализована функция добавления представленном на рисунке 3.5 пользователя в формате, Рисунок 3.5 - Добавление пользователя Предусмотрена функциональная возможность редактирования пользователя. Для выполнения данной процедуры, также осуществляется обращение к выбранному пункту меню и непосредственно ввод нужных параметров. Рисунок 3.6 Рисунок 3.6 – Редактирование пользователя Удаление пользователя показано на рисунке 3.7. Выполняется путем ввода необходимого пункта меню в заданное поле. 17 Рисунок 3.7 – Удаление пользователя Сортировка представлена на рисунке 3.8 Рисунок 3.8 – Удаление пользователя Работа с данными абонентов показана на рисунке 3.9. Представлена информация обо всех вызовах, путем выбора пункта меню «1». Транслируется подробная информация по выбранной категории (№ абонента, Ф.И.О, дата вызова, тип вызова). Далее, по запросу пользователя осуществляется работа с показанным перечнем меню. Рисунок 3.9 – Работа с данными 18 Добавление нового вызова показано на рисунке 3.10. Рисунок 3.10 – Добавление нового вызова Список всех вызовов и удаление записи показано на рисунке 3.11 Рисунок 3.11 – Список всех вызовов и удаление записи Удаление рейса показано на рисунке 3.11 19 Рисунок 3.11 – Удаление рейса В программе предусмотрена сортировка данных по разным параметрам. Эти процессы показаны на рисунке 3.12-3.14 Рисунок 3.12 – Сортировка по фамилии Рисунок 3.13 – Сортировка по номеру телефона 20 Рисунок 3.14 – Сортировка по номеру дате звонка Поиск по индивидуальным значениям. Для удобства, в начале учтено отображение с сортировкой по номеру абонента с учетом всех дат временным ограничением. Рисунок 3.15-3.16 Рисунок 3.15 – информация с учетом всех дат 21 Рисунок 3.16 – Информация с ограничением дат 22 3.2 Тестирование программы Тестирование необходимо для того, чтобы продуктивность и качество создаваемого продукта увеличились, время, необходимое для разработки, сократилось, и, полученный результат соответствовал установленным требованиям и критериям. Таким образом, можно обозначить, что тестирование играет важную роль в разработке качественного продукта. Целью тестирования является проверка всех функциональных возможностей программы и проведение серии тестов для выявления ее погрешностей. Тестирование компонентов — тестируется минимально возможный для тестирования компонент, например, отдельный класс или функция. Часто тестирование компонентов осуществляется разработчиками программного обеспечения. На рисунке 3.16 показан запуск программы и процесс поиска сопутствующих файлов. Система при этом, предлагает выйти из программы. Рисунок 3.16 – Проверка на наличия сопутствующих файлов При работе с данными, следует рассмотреть вариант ввода несуществующего пункта меню. В таком случае, программой предусмотрено сообщение о повторном вводе данных, с указанием существующего пункта меню. Рисунок 3.17 Рисунок 3.17 – Работа с данными. Ошибка ввода значения 23 Случай проверки при удалении пользователя показан на рисунке 3.18. Система предлагает к рассмотрению три возможных варианта выбора пользователя. В меню они представлены значениями от одного до трех. При вводе значения равному четырем, программа выдает сообщение об отсутствии такого пользователя. Рисунок 3.18 – Удаление информации. Случай некорректного ввода данных При работе со списком вызова может возникнуть ситуация выбора (указания) несуществующего пункта меню. В таком случае программа выдаст сообщение об отсутствии выбранного пункта меню. Рисунок 3.19 24 Рисунок 3.19 - Выбор количества билетов. Случай несоответствия количества 25 ЗАКЛЮЧЕНИЕ В ходе выполнения курсовой работы разработана система работы учета переговоров абонентов сотовой связи. Оператор сотовой связи хранит информацию о разговорах своих абонентов: номер абонента; ФИО абонента; указание принадлежности вызова к исходящему или входящему; номер исходящего или входящего вызова; дата звонка; время звонка; продолжительность разговора; тариф одной минуты. Выведены по каждому абоненту за требуемый период времени: перечень входящих и исходящих вызовов, общее время входящих вызовов, общее время исходящих вызовов, общую сумму на исходящие вызовы (требуемый период времени вводится с клавиатуры). Программа реализована на языке С++. На уровне конструирования использованы технологии нисходящего проектирования и принципов методологии структурного программирования. Освоены технологии нисходящего проектирования и принципов методологии структурного программирования. Результат этапа конструирования представляется в форме графических блок-схем алгоритмов. Работа, включая программную часть, уникальна, имеет соответствующие тематике имена переменных, констант, функций; комментарии; проработаны исключительные ситуации; добавлены функциональных возможностей с учетом задачи по разработке системы учета переговоров абонентов сотовой связи. На уровне программирования реализованы графические блок-схемы алгоритмов на языке С++. Результат этапа программирования представлен в форме проекта в среде разработки приложений на языке С++ - Microsoft Visual Studio. 26 СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ 1 Пахомов, Б. C++ и MS Visual для начинающих / Б. Пахомов. – М.: БХВ-Петербург, 2011. – – С. 2010 2 Понамарев, В. Программирование на C++/C# в [Электронный ресурс]. – Режим доступа: Visual Studio .NET 3 Страуструп Б. Программирование: принципы и практика использования C++, исправленное издание — М.: Вильямс, 2011. — 1248 с. 4 Шилдт Г. Полный справочник по C++ — 4-е изд. — М.: Вильямс, 2011. — 800 с. 5 Навроцкий, А.А. Основы алгоритмизации и программирования в среде Visual C++: учеб.-метод. пособие / А. А. Навроцкий. – Минск : БГУИР, 2014. – 160 с. 6 Шилдт, Г. С++ Базовый курс, 3-е издание / Г. Шилдт. Пер. с англ. – М.: Издательский дом «Вильямс», 2015. – 624 с. 7 Макконнелл, С. Совершенный код. Мастер-класс / С. Макконнелл. Пер. с англ. – М. : Издательство «Русская редакция», 2010. — 896 стр. 8 Документация по Visual Studio [электронный ресурс]. Режим доступа: https://docs.microsoft.com/ru-ru/visualstudio/ide/?view=vs-2017 27 ПРИЛОЖЕНИЕ А (обязательное) Блок-схемы алгоритмов Рисунок А.1 – Блок-схема алгоритма работы функции авторизации 28 Рисунок А.2 – Алгоритм функции для отображения пользователей на экране Рисунок А.3 – Алгоритм функции сортировки 29 ПРИЛОЖЕНИЕ Б (обязательное) Листинг программного кода Вар 5 Разработка программы учета переговоров абонентов сотовой связи Оператор сотовой связи хранит информацию о разговорах своих абонентов: номер абонента; ФИО абонента; указание принадлежности вызова к исходящему или входящему; номер исходящего или входящего вызова; дата звонка; время звонка; продолжительность разговора; тариф одной минуты. Вывести по каждому абоненту за требуемый период времени: перечень входящих и исходящих вызовов, общее время входящих вызовов, общее время исходящих вызовов, общую сумму на исходящие вызовы (требуемый период времени вводится с клавиатуры). Горовой Владислав Андреевич ИТ 862 */ #include <iostream> #include <fstream> #include <string> #include <iomanip> #include <vector> #include <iterator> #include <algorithm> //#include "windows.h" using namespace std; string file_users = "users.txt"; string file_abonent = "abonents.txt"; string PROGR_INFO = "\nАвтор - Горовой Владислав Андреевич" "\nГруппа ИТ 862" "\nРуководитель - Рябычина Ольга Петровна"; int const kol_users = 10; int const kol_abonents = 20; 30 // структура (список) пользователей struct User { string name; //имя пользователя string pass; //пароль int role; // 0 - админ 1...-пользователь }; // структура (список) об абонентах struct Abonent { string nomer; //Номер абонента; string familia; //Фамилия; string imya; //Имя; string otchestvo; //Отчество; bool tip_vizova; //Тип вызова (0-входящий, 1-исходящий) string nomer_x; //Номер исходящего или входящего вызова string data_x; //Дата звонка; string vremya_x; //Время звонка; float dlitelnost; //Продолжительность разговора; float tarif; //Тариф одной минуты; }; // функция авторизации пользователя в системе. Возвращает значение роли 0администратор 1-пользователь int authorization(); /*--------- Функции для отображения меню администратора ---------*/ // Функция стартового меню для администратора void adm_menu_start(); // Функция меню работы с пользователями для администратора void adm_menu_users(); // функция меню работы с абонентами для администратора void adm_menu_abonents(); // функция меню работы с абонентами для администратора //void adm_menu_abonents() /*--------- Функции для отображения меню пользователя ---------*/ // Функция стартового меню для администратора void user_menu_start(); /*--------- Функции для работы с пользователями ---------*/ // Функция считывания пользователей из файла в массив памяти arr_of_users void readUsers(User* arr_of_users, int& number_of_users); // Функция для отображения пользователей на экране void showUsers(User* arr_of_users, int number_of_users); // Функция для добавления нового пользователя в массив + дозапись в конец файла void addUserInArray(User* arr_of_users, int& number_of_users); // функция изменения пользователя и перезаписи файла void editUser(User* arr_of_users, int number_of_users); // Функция удаления пользователя 31 void dellUser(); // Функция для дозаписи нового пользователя в файл void writeEndFileUsers(User new_user); // Функция для перезаписи файла пользователей void writeFileUsers(User* arr_of_users, int number_of_users); // Функция сортировки пользователей по имени void sortUsers(User* arr_of_users, int& number_of_users); /*--------- Функции общего назначения ---------*/ // Функция для получения кол-ва записей в файле (путь к файлу) int getCountOfStucturesInFile(string file_path); // Функция для удаления строки (имя файла, номер строки) bool remove_line(string file_path, size_t index); /*--------- Функции для работы с данными по абонентами ---------*/ // Функция считывания списка вызовов из файла в массив памяти arr_of_abonents void readAbonents(Abonent* arr_of_abonents, int& number_of_abonents); // Функция для отображения списка вызовов на экране void showAbonents(Abonent* arr_of_abonents, int number_of_abonents); // Функция для добавления нового абонента в массив + дозапись в конец файла void addAbonentInArray(Abonent* arr_of_abonents, int& number_of_abonents); // Функция изменения абонента и перезаписи файла void editAbonent(Abonent* arr_of_abonents, int number_of_abonents); // Функция для перезаписи файла абонентов void writeFileAbonents(Abonent* arr_of_abonents, int number_of_abonents); // Функция для дозаписи нового абонента в файл void writeEndFileAbonents(Abonent new_abonent); // Функция удаления абонента void dellAbonent(); // Функция отображения вариантов сортировки и сортировки записей о абонентах void sortAbonents(Abonent* arr_of_abonents, int& number_of_abonents); // Функция отображения вариантов сортировки и сортировки записей о абонентах void vivod_po_IZ(Abonent* arr_of_abonents, int& number_of_abonents); // Функция бронирования билетов эконом класса int main() { //setlocale(LC_ALL, "ru"); SetConsoleCP(1251); SetConsoleOutputCP(1251); int role = authorization(); switch (role) { case 0: cout << "Вы авторизовались как администратор" << endl; adm_menu_start(); break; case 1: 32 cout << "Вы авторизовались как пользователь" << endl; user_menu_start(); break; default: cout << "ERROR!" << endl; break; } /* User arr_of_users[kol_users]; int number_of_users = 0; readUsers(arr_of_users, number_of_users); Abonent arr_of_abonents[kol_abonents]; int number_of_abonents = 0; vivod_po_IZ(arr_of_abonents, number_of_abonents); */ } // функция авторизации пользователя в системе. Возвращает значение роли 0администратор 1-пользователь int authorization() { User arr_of_users[kol_users]; int number_of_users = 0; readUsers(arr_of_users, number_of_users); string login; string pass; char repeat; cout << "******** Авторизация ********" << endl; TryAgain_Authorization: // это лейбл int type = 2; cout << "Введите логин: "; cin >> login; cout << "Введите пароль: "; cin >> pass; for (int i = 0; i < number_of_users; i++) { if (login == arr_of_users[i].name && pass == arr_of_users[i].pass) // условие - если введенные логин и пароль совпадают { type = arr_of_users[i].role; //переменной присваиваем значение 0 или 1 cout << endl << arr_of_users[i].name << " добро пожаловать в систему" << endl; } } if (type != 0 && type != 1) { cout << "Неверное имя или пароль" << endl; 33 cout << "Повторить?(y/n): " << endl; cin >> repeat; if (repeat == 'y') goto TryAgain_Authorization; else exit(0); } return type; авдмин) } //возврат рез-та авторизации (пользователь это или /*--------- Функции для отображения меню администратора ---------*/ // Функция стартового меню для администратора void adm_menu_start() // функция главного меню для администратора { char myChoice; cout << "********** Главное меню для администратра **********" << endl; cout << "1: Работа с пользователями" << endl; cout << "2: Работа с данными абонентов сотовой связи" << endl; cout << "9: Назад к авторизации" << endl; cout << "0: Выход из программы" << endl; cout << "?: Информация о программе" << endl; tryAgain_am1: cout << "\nВыберите пукт меню: "; cin >> myChoice; switch (myChoice) { case '1': adm_menu_users(); break; case '2': adm_menu_abonents(); break; case '9': main(); break; case '0': exit(0); case '?': cout << PROGR_INFO << endl; break; default: cout << "Такого пункта меню нет! Попробуйте снова." << endl; break; } goto tryAgain_am1; } // Функция меню работы с пользователями для администратора void adm_menu_users() { 34 char myChoice; User arr_of_users[kol_users]; int number_of_users = 0; cout << "********** Работа с пользователями **********" << endl; cout << "1: Показать данные всех пользователей" << endl; cout << "2: Добвить пользователя" << endl; cout << "3: Изменить пользователя" << endl; cout << "4: Удалить пользователей" << endl; cout << "5: Упорядочить пользователя" << endl; cout << "9: Назад главному меню" << endl; cout << "0: Выход из программы" << endl; cout << "?: Информация о программе" << endl; tryAgain_adm2: cout << "\nВыберите пукт меню: "; cin >> myChoice; switch (myChoice) { case '1': readUsers(arr_of_users, number_of_users); showUsers(arr_of_users, number_of_users);; break; case '2': addUserInArray(arr_of_users, number_of_users); break; case '3': editUser(arr_of_users, number_of_users); break; case '4': dellUser(); break; case '5': sortUsers(arr_of_users, number_of_users); break; case '9': adm_menu_start(); break; case '0': exit(0); case '?': cout << PROGR_INFO << endl; break; default: cout << "Такого пункта меню нет! Попробуйте снова." << endl; break; } goto tryAgain_adm2; } // функция меню работы с абонентами для администратора void adm_menu_abonents() { 35 char myChoice; Abonent arr_of_abonents[kol_abonents]; int number_of_abonents = 0; cout << "*** Работа с данными абонентов сотовой связи ***" << endl; cout << "1: Показать информацию обо всех вызовах" << endl; cout << "2: Добвить запись о вызове" << endl; cout << "3: Изменить запись о вызове" << endl; cout << "4: Удалить запись о вызове" << endl; cout << "5: Сортировка записей" << endl; cout << "6: Вывод информации о записях по условию ИЗ" << endl; cout << "9: Назад главному меню" << endl; cout << "0: Выход из программы" << endl; cout << "?: Информация о программе" << endl; tryAgain_am2: cout << "\nВыберите пукт меню: "; cin >> myChoice; switch (myChoice) { case '1': readAbonents(arr_of_abonents, number_of_abonents); showAbonents(arr_of_abonents, number_of_abonents); break; case '2': addAbonentInArray(arr_of_abonents, number_of_abonents); break; case '3': editAbonent(arr_of_abonents, number_of_abonents); break; case '4': dellAbonent(); break; case '5': sortAbonents(arr_of_abonents, number_of_abonents); break; case '6': vivod_po_IZ(arr_of_abonents, number_of_abonents); break; case '9': adm_menu_start(); break; case '0': exit(0); case '?': cout << PROGR_INFO << endl; break; default: cout << "Такого пункта меню нет! Попробуйте снова." << endl; break; } goto tryAgain_am2; } 36 /*--------- Функции для отображения меню пользователя ---------*/ // Функция стартового меню для администратора void user_menu_start() { char myChoice; Abonent arr_of_abonents[kol_abonents]; int number_of_abonents = 0; cout << "********** Работа с данными **********" << endl; cout << "1: Показать информацию обо всех абонентах" << endl; cout << "2: Сортировка абонентов" << endl; cout << "3: Вывод информации о записях по условию ИЗ" << endl; cout << "9: Назад" << endl; cout << "0: Выход из программы" << endl; cout << "?: Информация о программе" << endl; tryAgain_um1: cout << "\nВыберите пукт меню: "; cin >> myChoice; switch (myChoice) { case '1': readAbonents(arr_of_abonents, number_of_abonents); showAbonents(arr_of_abonents, number_of_abonents); break; case '2': sortAbonents(arr_of_abonents, number_of_abonents); break; case '3': vivod_po_IZ(arr_of_abonents, number_of_abonents); break; case '9': main(); break; case '0': exit(0); case '?': cout << PROGR_INFO << endl; break; default: cout << "Такого пункта меню нет! Попробуйте снова." << endl; break; } goto tryAgain_um1; } /*--------- Функции для работы с пользователями ---------*/ 37 // Функция считывания пользователей из файла в массив памяти arr_of_users void readUsers(User* arr_of_users, int& number_of_users) { ifstream fin(file_users.c_str(), ios::in); // Открыли файл для чтения if (!fin.is_open()) cout << "Указанный файл не существует!" << endl; else { int i = 0; while (!fin.eof()) { if (i < kol_users) { fin >> arr_of_users[i].name >> arr_of_users[i].pass >> arr_of_users[i].role; i++; } else { cout << "Недостаточно памяти для чтения всех данных!" << endl; break; } } number_of_users = i - 1; // отнимаем еденицу, т.к. есть доп пустая строка для новой записи } fin.close(); //Закрыли файл } // Функция для отображения пользователей на экране ---------*/ void showUsers(User* arr_of_users, int number_of_users) { cout << "*******************" << " Список пользователей " << "*******************" << endl; cout << "+------+-----------------+-------------+-------+" << endl; cout << "| ID | " << setw(14) << left << "Логин" << "| " << setw(10) << left << "Пароль" << "| " << "Роль" << " |" << endl; cout << "+------+-----------------+-------------+-------+" << endl; for (int i = 0; i < number_of_users; i++) cout << "| " << i + 1 << " | " << setw(14) << left << arr_of_users[i].name << "| " << setw(10) << left << arr_of_users[i].pass << "| " << arr_of_users[i].role << " |" << endl; cout << "+------+-----------------+-------------+-------+" << endl; } 38 // Функция для добавления нового пользователя в массив + дозапись в конец файла void addUserInArray(User* arr_of_users, int& number_of_users) { cout << "*******************" << " Добавление пользователя " << "*******************" << endl; //добавление пользователя, если не происходит выход за пределы массива if (number_of_users + 1 <= kol_users) { number_of_users++; cout << "Добавление нового пользователя " << endl; cout << "Введите имя пользователя: "; cin >> arr_of_users[number_of_users - 1].name; cout << "Введите пароль: "; cin >> arr_of_users[number_of_users - 1].pass; cout << "Определите роль (0-адм, 1-польз): "; cin >> arr_of_users[number_of_users - 1].role; writeEndFileUsers(arr_of_users[number_of_users - 1]); cout << "Пользователь " << arr_of_users[number_of_users - 1].name << " добавлен" << endl; } else cout << "Недостаточно памяти для добавления нового элемента!" << endl; } // Функция изменения пользователя и перезаписи файла void editUser(User* arr_of_users, int number_of_users) { cout << "*******************" << " Редактирование пользователя " << "*******************" << endl; int id = 100; readUsers(arr_of_users, number_of_users); cout << "Изменение пользователя" << endl; cout << "Введите ID пользователя, для изменения "; cin >> id; id = id - 1; if (id > number_of_users - 1) { cout << "Такого пользователя не существует." << endl << "Проверьте вводимые данные!" << endl; } else { cout << "Имя: "; cin >> arr_of_users[id].name; cout << "Пароль: "; cin >> arr_of_users[id].pass; cout << "Роль: "; cin >> arr_of_users[id].role; 39 cout << "Данные пользователя #" << id+1 << " " << arr_of_users[id].name << " изменены" << endl; writeFileUsers(arr_of_users, number_of_users); } } // Функция удаления пользователя void dellUser() { cout << "*******************" << " Удаление пользователя " << "*******************" << endl; int id = 0; int k = getCountOfStucturesInFile(file_users); cout << "Удаление пользователя" << endl; cout << "Введите ID пользователя для удаления "; cin >> id; if (id <= k) { remove_line(file_users, id); cout << "Пользователь # " << id << " удален" << endl; } else cout << "Такого пользователя не существует." << endl << "Проверьте вводимые данные!" << endl; } // Функция для дозаписи нового пользователя в файл void writeEndFileUsers(User new_user) { ofstream fadd(file_users.c_str(), ios::app); // Открыли файл для дозаписи fadd << new_user.name << "\t" << new_user.pass << "\t" << new_user.role << endl; fadd.close(); } // Функция для перезаписи файла пользователей void writeFileUsers(User* arr_of_users, int number_of_users) { ofstream fout(file_users, ios::out); // Открыли файл для записи for (int i = 0; i < number_of_users; i++) { fout << arr_of_users[i].name << "\t" << arr_of_users[i].pass << "\t" << arr_of_users[i].role; if (i < number_of_users - 1) { fout << endl; 40 } } fout << endl; fout.close(); } // Функция отображения вариантов сортировки и сортировки записей void sortUsers(User* arr_of_users, int& number_of_users) { readUsers(arr_of_users, number_of_users); User temp; // временная переменная для обмена элементов местами // Сортировка массива пузырьком for (int i = 0; i < number_of_users - 1; i++) { for (int j = 0; j < number_of_users - i - 1; j++) { if (arr_of_users[j].name > arr_of_users[j + 1].name) { // меняем элементы местами temp = arr_of_users[j]; arr_of_users[j] = arr_of_users[j + 1]; arr_of_users[j + 1] = temp; } } } showUsers(arr_of_users, number_of_users); } /*--------- Функции общего назначения ---------*/ // Функция для получения кол-ва записей в файле int getCountOfStucturesInFile(string file_path) { ifstream file(file_path.c_str(), ios::in); // Открыли текстовый файл для чтения int number_of_strings = 0; if (file.is_open()) { string buffer; while (getline(file, buffer)) number_of_strings++; } file.close(); return number_of_strings; } // Функция для удаления строки (имя файла, номер строки) bool remove_line(string file_path, size_t index) { vector<string> vec; ifstream file(file_path); 41 if (file.is_open()) { string str; while (getline(file, str)) vec.push_back(str); file.close(); if (vec.size() < index - 1) return false; vec.erase(vec.begin() + index - 1); ofstream outfile(file_path); if (outfile.is_open()) { copy(vec.begin(), vec.end(), ostream_iterator<string>(outfile, "\n")); outfile.close(); return true; } return false; } return false; } /*--------- Функции для работы с данными по абонентам ---------*/ // Функция считывания списка вызовов из файла в массив памяти arr_of_abonents void readAbonents(Abonent* arr_of_abonents, int& number_of_abonents) { ifstream fin(file_abonent, ios::in); // Открыли файл для чтения if (!fin.is_open()) cout << "Указанный файл не существует!" << endl; else { int i = 0; while (!fin.eof()) { if (i < kol_abonents) { fin >> arr_of_abonents[i].nomer >> arr_of_abonents[i].familia >> arr_of_abonents[i].imya >> arr_of_abonents[i].otchestvo >> arr_of_abonents[i].tip_vizova >> arr_of_abonents[i].nomer_x >> arr_of_abonents[i].data_x >> arr_of_abonents[i].vremya_x >> arr_of_abonents[i].dlitelnost >> arr_of_abonents[i].tarif; i++; } else 42 { cout << "Недостаточно памяти для чтения всех данных!" << endl; break; } } number_of_abonents = i - 1; строка для новой записи } fin.close(); //Закрыли файл } // отнимаем еденицу, т.к. есть доп пустая // Функция для отображения списка вызовов на экране void showAbonents(Abonent* arr_of_abonents, int number_of_abonents) { cout << "*************************************************" << " Список всех вызовов " << "*************************************************" << endl; cout << "+----+-----------+-------------------------------+----------" << "+-------------+-----------+-----------+------------+-------+" << endl; cout << "| ID | " << setw(10) << left << "# абонента" << "|" << setw(12) << left << " " << setw(19) << left << "Ф.И.О" << "|" << setw(10) << left << "Тип вызова" << "|" << setw(12) << left << "# др абонента" << "|" << setw(11) << left << "Дата вызова" << "| " << setw(10) << left << "Вр вызова" << "|" << setw(10) << left << "Длительность" << "| " << setw(6) << left << "Тариф" << "|" << endl; cout << "+----+-----------+-------------------------------+----------" << "+-------------+-----------+-----------+------------+-------+" << endl; for (int i = 0; i < number_of_abonents; i++) { cout << "| " << i + 1 << " | " << setw(10) << left << arr_of_abonents[i].nomer << "| " << setw(8) << left << arr_of_abonents[i].familia << setw(8) << left << arr_of_abonents[i].imya << setw(14) << left << arr_of_abonents[i].otchestvo << "| " << setw(6) << left << arr_of_abonents[i].tip_vizova << "| " << setw(11) << left << arr_of_abonents[i].nomer_x << "| " << setw(10) << left << arr_of_abonents[i].data_x << "| " << setw(8) << left << arr_of_abonents[i].vremya_x << "| " << setw(7) << left << arr_of_abonents[i].dlitelnost << "| " << setw(5) << left << arr_of_abonents[i].tarif << "|"<< endl; cout << "+----+-----------+-------------------------------+----------" << "+-------------+-----------+-----------+------------+-------+" << endl; } 43 } // Функция для добавления нового абонента в массив + дозапись в конец файла void addAbonentInArray(Abonent* arr_of_abonents, int& number_of_abonents) { cout << "***********************************************" << " Добавление вызова " << "***********************************************" << endl; if (number_of_abonents + 1 <= kol_abonents) { number_of_abonents++; cout << "Добавление нового абонента " << endl; cout << "Номер абонента (###-##-##): "; cin >> arr_of_abonents[number_of_abonents - 1].nomer; cout << "Фамилия: "; cin >> arr_of_abonents[number_of_abonents - 1].familia; cout << "Имя: "; cin >> arr_of_abonents[number_of_abonents - 1].imya; cout << "Отчество: "; cin >> arr_of_abonents[number_of_abonents - 1].otchestvo; cout << "Тип вызова (0-для входящих, 1-для входящих): "; cin >> arr_of_abonents[number_of_abonents - 1].tip_vizova; cout << "Номер исходящего или входящего вызова (###-##-##): "; cin >> arr_of_abonents[number_of_abonents - 1].nomer_x; cout << "Дата звонка (гггг.мм.дд): "; cin >> arr_of_abonents[number_of_abonents - 1].data_x; cout << "Время звонка (чч:мм): "; cin >> arr_of_abonents[number_of_abonents - 1].vremya_x; cout << "Продолжительность разговора (мин): "; cin >> arr_of_abonents[number_of_abonents - 1].dlitelnost; cout << "Тариф одной минуты (усл.ед.): "; cin >> arr_of_abonents[number_of_abonents - 1].tarif; writeEndFileAbonents(arr_of_abonents[number_of_abonents - 1]); cout << "Вызов " << arr_of_abonents[number_of_abonents - 1].nomer << " добавлен" << endl; } else cout << "Недостаточно памяти для добавления нового элемента!" << endl; } // Функция изменения абонента и перезаписи файла void editAbonent(Abonent* arr_of_abonents, int number_of_abonents) { cout << "***********************************************" << " Редактирование вызова " << "***********************************************" << endl; int id = 0; readAbonents(arr_of_abonents, number_of_abonents); cout << "Введите ID вызова, который необходимо изменить" << endl; cin >> id; id = id - 1; 44 if (id > number_of_abonents - 1) cout << "Такой записи не существует." << endl << "Проверьте вводимые данные!" << endl; else { cout << "Номер абонента (###-##-##): "; cout << arr_of_abonents[id].nomer << " -> "; cin >> arr_of_abonents[id].nomer; cout << arr_of_abonents[id].nomer << " -> "; cout << "Фамилия: "; cout << arr_of_abonents[id].familia << " -> "; cin >> arr_of_abonents[id].familia; cout << "Имя: "; cout << arr_of_abonents[id].imya << " -> "; cin >> arr_of_abonents[id].imya; cout << "Отчество: "; cout << arr_of_abonents[id].otchestvo << " -> "; cin >> arr_of_abonents[id].otchestvo; cout << "Тип вызова (0-для входящих, 1-для входящих): "; cout << arr_of_abonents[id].tip_vizova << " -> "; cin >> arr_of_abonents[id].tip_vizova; cout << "Номер исходящего или входящего вызова: "; cout << arr_of_abonents[id].nomer_x << " -> "; cin >> arr_of_abonents[id].nomer_x; cout << "Дата звонка (гггг.мм.дд): "; cout << arr_of_abonents[id].data_x << " -> "; cin >> arr_of_abonents[id].data_x; cout << "Время звонка (чч:мм): "; cout << arr_of_abonents[id].vremya_x << " -> "; cin >> arr_of_abonents[id].vremya_x; cout << "Продолжительность разговора (мин): "; cout << arr_of_abonents[id].dlitelnost << " -> "; cin >> arr_of_abonents[id].dlitelnost; cout << "Тариф одной минуты (усл.ед.): "; cout << arr_of_abonents[id].tarif << " -> "; cin >> arr_of_abonents[id].tarif; cout << "Абонент изменен" << endl; } writeFileAbonents(arr_of_abonents, number_of_abonents); } // Функция для перезаписи файла списка вызовов void writeFileAbonents(Abonent* arr_of_abonents, int number_of_abonents) { ofstream fout(file_abonent, ios::out); // Открыли файл для записи for (int i = 0; i < number_of_abonents; i++) { fout << arr_of_abonents[i].nomer << "\t" << arr_of_abonents[i].familia << "\t" << arr_of_abonents[i].imya << "\t" << arr_of_abonents[i].otchestvo << "\t" 45 << << << << << << arr_of_abonents[i].tip_vizova << "\t" arr_of_abonents[i].nomer_x << "\t" arr_of_abonents[i].data_x << "\t" arr_of_abonents[i].vremya_x << "\t" arr_of_abonents[i].dlitelnost << "\t" arr_of_abonents[i].tarif << "\t"; if (i < number_of_abonents - 1) { fout << endl; } } fout << endl; fout.close(); } // Функция для дозаписи нового абонента в файл void writeEndFileAbonents(Abonent new_abonent) { ofstream fadd(file_abonent, ios::app); // Открыли файл для дозаписи fadd << new_abonent.nomer << "\t" << new_abonent.familia << "\t" << new_abonent.imya << "\t" << new_abonent.otchestvo << "\t" << new_abonent.tip_vizova << "\t" << new_abonent.nomer_x << "\t" << new_abonent.data_x << "\t" << new_abonent.vremya_x << "\t" << new_abonent.dlitelnost << "\t" << new_abonent.tarif << endl; fadd.close(); } // Функция удаления абонента void dellAbonent() { cout << "***********************************************" << " Удаление записи " << "***********************************************" << endl; int id = 0; int k = getCountOfStucturesInFile(file_abonent); cout << "Введите ID записи для удаления: " ; cin >> id; if (id <= k) { remove_line(file_abonent, id); cout << "Вызов #" << id << " удален" << endl; } else cout << "Такого вызова не существует." << endl << "Проверьте вводимые данные!" << endl; 46 } // Функция отображения вариантов сортировки и сортировки записей void sortAbonents(Abonent* arr_of_abonents, int& number_of_abonents) { char myChoice; Abonent temp; cout << "********** Сортировка **********" << endl; cout << "1: Упорядочить записи по фамилии абонента" << endl; cout << "2: Упорядочить записи по номеру телефона" << endl; cout << "3: Упорядочить записи по дате звонка" << endl; cout << "9: Назад " << endl; cout << "0: Выход из программы" << endl; cout << "?: Информация о программе" << endl; tryAgain_sort: cout << "\nВыберите пукт меню: "; cin >> myChoice; switch (myChoice) { case '1': readAbonents(arr_of_abonents, number_of_abonents); for (int i = 0; i < number_of_abonents - 1; i++) { for (int j = 0; j < number_of_abonents - i - 1; j++) { if (arr_of_abonents[j].familia > arr_of_abonents[j + 1].familia) { // меняем элементы местами temp = arr_of_abonents[j]; arr_of_abonents[j] = arr_of_abonents[j + 1]; arr_of_abonents[j + 1] = temp; } } } showAbonents(arr_of_abonents, number_of_abonents); break; case '2': readAbonents(arr_of_abonents, number_of_abonents); for (int i = 0; i < number_of_abonents - 1; i++) { for (int j = 0; j < number_of_abonents - i - 1; j++) { if (arr_of_abonents[j].nomer > arr_of_abonents[j + 1].nomer) { // меняем элементы местами temp = arr_of_abonents[j]; arr_of_abonents[j] = arr_of_abonents[j + 1]; arr_of_abonents[j + 1] = temp; } } } 47 showAbonents(arr_of_abonents, number_of_abonents); break; case '3': readAbonents(arr_of_abonents, number_of_abonents); for (int i = 0; i < number_of_abonents - 1; i++) { for (int j = 0; j < number_of_abonents - i - 1; j++) { if (arr_of_abonents[j].data_x > arr_of_abonents[j + 1].data_x) { // меняем элементы местами temp = arr_of_abonents[j]; arr_of_abonents[j] = arr_of_abonents[j + 1]; arr_of_abonents[j + 1] = temp; } } } showAbonents(arr_of_abonents, number_of_abonents); break; case '9': main(); break; case '0': exit(0); case '?': cout << PROGR_INFO << endl; break; default: cout << "Такого пункта меню нет! Попробуйте снова." << endl; break; } goto tryAgain_sort; } // Функция отображения вариантов сортировки и сортировки записей о абонентах void vivod_po_IZ(Abonent* arr_of_abonents, int& number_of_abonents) { readAbonents(arr_of_abonents, number_of_abonents); Abonent temp; int k = 0; string search_num; int tickets_num = 0; int id = 100; string date_nach; string date_konec; cout << "****** Поиск в соответствии с ИЗ: *****" << endl; cout << "Введите начальную дату для поиска (чччч.мм.дд): "; cin >> date_nach; cout << "Введите конечную дату для поиска (чччч.мм.дд): "; cin >> date_konec; //Вначале отсортируем 48 for (int i = 0; i < number_of_abonents - 1; i++) { for (int j = 0; j < number_of_abonents - i - 1; j++) { if (arr_of_abonents[j].nomer > arr_of_abonents[j + 1].nomer) { // меняем элементы местами temp = arr_of_abonents[j]; arr_of_abonents[j] = arr_of_abonents[j + 1]; arr_of_abonents[j + 1] = temp; } } } for (int i = 0; i < 5;) { cout << "-> Абонент: " << arr_of_abonents[i].familia << " " << arr_of_abonents[i].imya << " " << arr_of_abonents[i].otchestvo << "\n Номер: " << arr_of_abonents[i].nomer << endl; cout << " Список вызовов: " << endl; string isk_nomer; isk_nomer = arr_of_abonents[i].nomer; int k = 0; if (arr_of_abonents[i].nomer == isk_nomer) { float vhod_dlit = 0; float ish_dlit = 0; float ish_stoimost = 0; int kol_pod_usl = 0; for (int j = 0; j < number_of_abonents; j++) { if (arr_of_abonents[j].nomer == isk_nomer && arr_of_abonents[j].tip_vizova == 1) { if (arr_of_abonents[j].data_x >= date_nach && arr_of_abonents[j].data_x <= date_konec) { cout << " Исходящий: " << arr_of_abonents[j].nomer_x << " длит. " << arr_of_abonents[j].dlitelnost << " мин" << endl; ish_dlit = ish_dlit + arr_of_abonents[j].dlitelnost; ish_stoimost = ish_stoimost + (arr_of_abonents[j].dlitelnost * arr_of_abonents[j].tarif); kol_pod_usl++; } k++; 49 } else if (arr_of_abonents[j].nomer == isk_nomer && arr_of_abonents[j].tip_vizova == 0) { if (arr_of_abonents[j].data_x >= date_nach && arr_of_abonents[j].data_x <= date_konec) { cout << " Входящий: " << arr_of_abonents[j].nomer_x << " длит. " << arr_of_abonents[j].dlitelnost << " мин" << endl; vhod_dlit = vhod_dlit + arr_of_abonents[j].dlitelnost; kol_pod_usl++; } k++; } } if (kol_pod_usl == 0) cout << " По данному абоненту в заданный период времени вызовов не найдено " << endl; else { cout << " -------------------------------" << endl; cout << " Общая длительность входящих - " << vhod_dlit << " мин" << endl; cout << " Общая длительность исходящих - " << ish_dlit << " мин" << endl; cout << " Общая сумма на исходящие - " << ish_stoimost << " руб\n" << endl; } } i = i + k; } } 50 ПРИЛОЖЕНИЕ В Презентация разработанного ПО Рисунок В.1- Титульный слайд презентации Рисунок В.2- Слайд «Цель работы» 51 Рисунок В.3- Слайд «Исходные данные к работе» Рисунок В.4- Слайд «Структура/диаграмма ПО» 52 Рисунок В.5- Слайд «Описание структур» Рисунок В.6- Слайд демонстрации ПО 53 Рисунок В.7- Слайд тестирования ПО Рисунок В.8- Слайд демонстрации разработки алгоритмов 54 Рисунок В.9- Слайд демонстрации разработки алгоритмов Рисунок В.10- Слайд демонстрации разработки алгоритмов 55 Рисунок В.11 - Слайд демонстрации разработки Рисунок В.12 – Заключительный слайд 56