Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Пример отчета по домашнему заданию.doc
Скачиваний:
4
Добавлен:
14.09.2019
Размер:
179.2 Кб
Скачать

5 Руководство пользователя

Сразу же после запуска программы на экране компьютера отобразится консольное окно, приведенное на рисунке 1.

Рисунок 1 – Консольное окно программы

Программа выводит на экран текстовое меню поддерживаемых команд и ожидает, чтобы пользователь ввел номер выбранного им пункта меню.

Меню программы включает следующие пункты:

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

  2. Удаление сведений о спортсмене. Программа запросит номер удаляемой записи и удалит ее. Если будет указан номер несуществующей записи, то программа сообщит об этом.

  3. Поиск записей по фамилии. Программа запросит фамилию спортсмена и отобразит таблицу, содержащую сведения о спортсменах, имеющих данную фамилию.

  4. Сортировка записей о спортсменах в порядке не возрастания количества сыгранных игр.

  5. Вывод в виде таблицы записей обо всех спортсменах.

  6. Выход из программы.

Если пользователь укажет несуществующий пункт меню, то программа сообщит об этом.

Данная программа хранит все сведения о спортсменах в файле Sportsmen.dat, загружая их в память при запуске и сохраняя их при выходе из программы.

Список использованных источников

  1. Павовская, Т.А. Программирование на языке высокого уровня. – СПб.: Питер, 2004 г.

  2. Окулов, С.М. Программирование в алгоритмах: Учеб. изд / С.М. Окулов . - М. : БИНОМ : Лаборатория знаний, 2002.

  3. Кормен, Т. Алгоритмы: построение и анализ. – М.: МЦНМО, 2002.

Приложение а – Текст программы (обязательное)

//Подключаем заголовочный файл для работы со стандартными потоками cin и cout

#include <iostream>

//Подключаем заголовочный файл для работы с потоковыми манипуляторами

// (см. Павловская "Программирование на языке высокого уровня", с. 271 )

#include <iomanip>

//Подключаем заголовчный файл для работы с потоковыми файловыми классами

#include <fstream>

//Подключаем заголовочный файл для работы со строками

#include <string.h>

using namespace std;

// Константы

const int MAX_NAME_LENGTH = 100; //Максимальная длина фамилии, имени, отчества

const int MAX_SPORTSMEN_COUNT = 1000; //Максимальное количество спортсменов в массиве

const char* FILE_NAME = "sportsmen.dat"; //Имя файла для хранения записей о спортсменах

//Заголовочная константная строка, используемая при выводе записей

const char* HEADER = "Index Surname Name Patronymic Birth date Sport Games count";

//Разделительная линия

const char* SEPARATING_LINE = "-------------------------------------------------------------------------------";

//Перечисление, описывающее вид спорта

// skNone - вид спорта не указан;

// skTennis - теннис,

// skChess - шахматы,

// skSprint - бег

enum SportKind {skNone, skTennis, skChess, skSprint};

//Стуктура, описывающая дату

struct Date

{

unsigned short int Year; //Год

unsigned short int Month; //Месяц

unsigned short int Day; //День

};

//Структура, описывающая запись о спортсмене

struct Sportsman

{

char Surname[MAX_NAME_LENGTH + 1]; //Фамилия

char Name[MAX_NAME_LENGTH + 1]; //Имя

char Patronymic[MAX_NAME_LENGTH + 1]; //Отчество

Date DateOfBirth; //Дата рождения

SportKind KindOfSport; //Вид спорта

int GamesCount; //Количество сыгранных игр

};

//Вспомогательная функция, осуществляющая преобразование

//вида спорта, содержашегося в параметре Type в строку Str,

//т.е. в назваие спорта, представленное в виде строки

void SportKindToStr(SportKind Type, char Str[])

{

//В зависимости от значения Type

switch (Type)

{

case skTennis:

strcpy(Str, "tennis"); //Копируем в Str название вида спорта "tennis"

break;

case skChess:

strcpy(Str, "chess"); //Копируем в Str название вида спорта "chess"

break;

case skSprint:

strcpy(Str, "sprint"); //Копируем в Str название вида спорта "sprint"

break;

default:

strcpy(Str, "unknown"); //Случай, когда задан тип skNone

}

}

//Вспомогательная функция, которая по названию спорта, содержащемся в строке Str,

//возвращает его тип

SportKind StrToSportKind(char Str[])

{

//Переводим строку Str к нижнему регистру

strlwr(Str);

//Если строка Str равна "tennis", то возвращаем skTennis

if (!strcmp(Str, "tennis"))

return skTennis;

//Если строка Str равна "chess", то возвращаем skСhess

if (!strcmp(Str, "chess"))

return skChess;

//Если строка Str равна "sprint", то возвращаем skSprint

if (!strcmp(Str, "sprint"))

return skSprint;

//Если в строке недопустимое название вида спорта, то возвращаем skNone

return skNone;

}

//Функция, осуществляющая ввод записи о спортсмене с консоли.

//Введенная запись возвращается в параметре Man, передаваемом по ссылке

void InputSportsman(Sportsman& Man)

{

//Про потоковые классы (в частности про объект cin) можно почитать в

//Павловской "Программирование на языке высокого уровня" c. 265 - 285

//В частности про функции get() и getline() стандартного объекта ввода cin можно почитать на с. 273

// cin.get() - читает один символ с консоли;

// cin.getline(buf, num) - читает с консоли num-1 или пока не встретится символ перевода строки и

// помещает их в строку buf. Причем, если встретился символ перевода строки, то

// он тоже помещается в buf

char Buf[MAX_NAME_LENGTH]; //Вспомогательная строка для ввода данных

bool IsValidKindOfSport; //Логическая переменная, определяющая правильно ли введен вид спорта

//Читаем символ перевода строки

cin.get();

cout << endl;

cout << "Enter sportsman info" << endl;

//Вводим фамилию

cout << "Surname : ";

cin.getline(Man.Surname, sizeof Man.Surname);

//Вводим имя

cout << "Name : ";

cin.getline(Man.Name, sizeof Man.Name);

//Вводим отчество

cout << "Patronymic : ";

cin.getline(Man.Patronymic, sizeof Man.Patronymic);

//Вводим год рождения

cout << "Year of birth : ";

cin >> Man.DateOfBirth.Year;

//Вводим месяц рождения.

// <== Сюда можно добавить цикл с постусловием для проверки корректности ввода номера месяца

cout << "Month of birth (1-12) : ";

cin >> Man.DateOfBirth.Month;

//Вводим день рождения

// <== Сюда можно добавить цикл с постусловием для проверки корректности ввода дня

cout << "Day of birth (1-31) : ";

cin >> Man.DateOfBirth.Day;

// <== Сюда можно добавить корректность вводимой даты, т.е. проверки допустима ли введенная дата

//Читаем символ перевода строки

cin.get();

//Цикл с постусловием для повторного ввода строки вида спорта,

//если она отличная от "tennis", "chess" и "sprint"

do

{

//Полагаем, что вид спорта правильный

IsValidKindOfSport = true;

cout << "Kind of sport (tennis, chess or sprint) : ";

//Читаем в Buf строку вида спорта

cin.getline(Buf, sizeof Buf);

//Преобразовывем введенную строку в переменную типа SportKind

Man.KindOfSport = StrToSportKind(Buf);

//Если была введена недопустимая строка

if (Man.KindOfSport == skNone)

{

//Выдаем сообщение, что строка неправильная

cout << endl << "Invalid! Enter tennis, chess or sprint" << endl << endl;

//Устанавливаем значение лжи для флага правильности строки вида спорта

IsValidKindOfSport = false;

}

//Цикл повторяется до тех пор, пока введенная строка вида спорта не будет правильной

} while (!IsValidKindOfSport);

//Вводим количество сыгранных игр

cout << "Games count : ";

cin >> Man.GamesCount;

}

//Функция вывода на консоль полей записи (структуры) Man, имеющей индекс Index

void PrintSportsman(Sportsman Man, int Index)

{

//В данной функции используются специальные манипуляторы, осуществляющие форматирование

//выводимых данных. Для их использования необходимо подключить заголовочный файл iomanip.h

// setw(int) - устанавливает максимальную ширину поля вывода;

// setfill(char) - устанавливает символ-заполнитель для случая, если выводимые данные занимают не всю ширину

// поля вывода. По умолчанию символом-заполнителем является пробел

//Пример. Строка

// cout << setfill('+') << setw(5) << 44;

//выдаст на консоль

//+++44

//Подробности см. в Павловской "Программирование на языке высокого уровня" c. 271

char Buf[MAX_NAME_LENGTH]; //Строковая переменная для строкового представления вида спорта

//Выводим индекс в поле максимальной ширины 5

cout << setw(5) << Index << " ";

//Выводим фамилию, имя, отчество. Каждое в своем поле максимальной ширины 13

cout << setw(13) << Man.Surname << " " << setw(13) << Man.Name << " "<< setw(13) << Man.Patronymic << " ";

//Меняем символ-заполнитель с пробела на 0. Использование заполнителя 0 позволит выдавать даты в формате ДД.ММ.ГГГГ

cout << setfill('0');

//Выдаем день, месяц и год даты рождение. Каждая компонента даты выводися в своем поле

cout << setw(2) << Man.DateOfBirth.Day << "." << setw(2) << Man.DateOfBirth.Month << "." << setw(4) << Man.DateOfBirth.Year << " ";

//Возвращаем пробел в качестве символа-заполнителя

cout << setfill(' ');

//Осуществляем перевод вида спорта в строку Buf

SportKindToStr(Man.KindOfSport, Buf);

//Выводим строку вида спорта и количество сыгрнанных игр

cout << setw(6) << Buf << " " << setw(7) << Man.GamesCount << endl;

}

//Функция, добавляющая запись о спортсмене Man в конец массива спортсменов SportsmenArray,

//SportsmenCount - количество записей-элементов в массиве SportsmenArray

void AddSportsman(Sportsman SportsmenArray[], int& SportsmenCount, Sportsman Man)

{

SportsmenArray[SportsmenCount++] = Man;

}

//Функция, удаляющая в массиве SportsmenArray запись-элемент с индексом RemovingIndex,

//SportsmenCount - количество записей-элементов в массиве SportsmenArray.

//Функция возвращает истину, если RemovingIndex лежит в допустимом диапазоне от 0 до SportsmenCount-1,

//иначе функция возвращает ложь

bool RemoveSportsman(Sportsman SportsmenArray[], int& SportsmenCount, int RemovingIndex)

{

//Если индекс удаляемого элемента задан неправильно, то возвращаем ложь

if (RemovingIndex < 0 || RemovingIndex >= SportsmenCount)

{

return false;

}

//Данный цикл осуществляет сдвиг элементов

// SportsmenArray[RemovingIndex], SportsmenArray[RemovingIndex], ..., SportsmenArray[SportsmenCount - 1]

//на один элемент влево и тем самым затирает удаляемый элемент

for (int i = RemovingIndex; i < SportsmenCount - 1; i++)

{

SportsmenArray[i] = SportsmenArray[i + 1];

}

//Уменьшаем количество элементов-записей на 1

SportsmenCount--;

//Возвращаем истину

return true;

}

//Функция, осуществляющая поиск и вывод на консоль элементов-записей о спортсменах массива SportsmenArray,

//фамилия которых совпадает со строкой KeySurname (ключом для поиска).

//SportsmenCount - количество записей-элементов в массиве SportsmenArray.

void SearchAndPrintSportsmen(Sportsman SportsmenArray[], int SportsmenCount, char KeySurname[])

{

//Переменная для подсчета количества найденных записей, вначале равна 0

int FoundRecordsCount = 0;

cout << endl;

//Выводим заголовок

cout << SEPARATING_LINE << endl;

cout << HEADER << endl;

cout << SEPARATING_LINE << endl;

//Пробегаемся по все элементам массива SportsmenArray

for (int i = 0; i < SportsmenCount; i++)

{

//Если фамилия очередного элемента-записи совпадает с KeySurname, то

if (!strcmp(SportsmenArray[i].Surname, KeySurname))

{

//выводим сам элемент

PrintSportsman(SportsmenArray[i], i);

//выводим разделительную линию

cout << SEPARATING_LINE << endl;

//Увеличиваем на 1 количество найденных записей

FoundRecordsCount++;

}

}

//Выводим количество найденных записей

cout << FoundRecordsCount << " records were found." << endl;

}

//Функция, осуществляющая сортировку массива спортсменов по не возрастанию количества сыгранных игр.

//SportsmenArray - массив элементов-записей о спортсменах;

//SportsmenCount - количество спорстменов-записей в массиве.

void SortSportsmenByGamesCount(Sportsman SportsmenArray[], int SportsmenCount)

{

int MaxIndex;

Sportsman Tmp;

for (int i = 0; i < SportsmenCount - 1; i++)

{

MaxIndex = i;

for (int j = i + 1; j < SportsmenCount; j++)

{

if (SportsmenArray[j].GamesCount > SportsmenArray[MaxIndex].GamesCount)

{

MaxIndex = j;

}

}

Tmp = SportsmenArray[i];

SportsmenArray[i] = SportsmenArray[MaxIndex];

SportsmenArray[MaxIndex] = Tmp;

}

}

//Функция, осуществляющая вывод на консоль всех элеменов-записей о спорстменах,

//содержащихся в массиве SportsmenArray размера SportsmenCount

void PrintAllSportsmen(Sportsman SportsmenArray[], int SportsmenCount)

{

cout << endl;

//Выводим заголовок

cout << SEPARATING_LINE << endl;

cout << HEADER << endl;

cout << SEPARATING_LINE << endl;

//Пробегаемя по всем элементам

for (int i = 0; i < SportsmenCount; i++)

{

//Выводим очердной элемент-запись

PrintSportsman(SportsmenArray[i], i);

//Выводим разделительную линию

cout << SEPARATING_LINE << endl;

}

}

//Функция, осуществляющая чтение массива SportsmenArray и его размера SportsmenCount

//из файла с именем SportsmenCount

void LoadFromFile(Sportsman SportsmenArray[], int& SportsmenCount, const char* FileName)

{

//Объявлем файловый поток ввода inp, передаем ему имя открываемого файла FileName

ifstream inp(FileName);

//Читаем из файла количество элементов в массиве

inp >> SportsmenCount;

//Читаем из файла целиком весь массив

inp.read((char *)SportsmenArray, SportsmenCount * sizeof(SportsmenArray[0]));

}

//Функция, осуществляющая сохранение массива SportsmenArray и его размера SportsmenCount

//в файл FileName

void SaveToFile(Sportsman SportsmenArray[], int SportsmenCount, const char* FileName)

{

//Объявляем файловый поток вывода out, передаем ему имя открываемого файла FileName

ofstream out(FileName);

//Записываем в файл количество спорстменов

out << SportsmenCount;

//Записываем в файл весь массив целиком

out.write((char *)SportsmenArray, SportsmenCount * sizeof(SportsmenArray[0]));

}

//Функция, реализующая главное меню программы. В зависимости от выбора пользователя,

//осуществляет вызов соответствующих функций.

//Параметры:

//SportsmenArray - массив элементов-записей о спорстменах;

//SportsmenCount - количество элементов в массиве.

void MainMenu(Sportsman SportsmenArray[], int& SportsmenCount)

{

//Переменная, которая будет хранить номер выбранного пользователем пункта меню

int UserChoise;

//Переменная-запись о спорстмене

Sportsman Man;

//Переменная для хранения индекса удаляемого элемента

int RemovingIndex;

//Массив символов для хранения строки фамилии для поиска

char KeySurname[MAX_NAME_LENGTH];

//Цикл с постусловием, осуществляющий вывод меню, ввод выбора пользователя и

//выполнение соответстующих этому выбору действий до тех пор, пока пользователь

//не выберет выход из программы

do

{

//Отображаем меню

cout << endl;

cout << " MENU" << endl;

cout << "=========================" << endl;

cout << " [1] Add sportsman" << endl;

cout << " [2] Remove sportsman" << endl;

cout << " [3] Search sportsman" << endl;

cout << " [4] Sort sportsmen" << endl;

cout << " [5] Show all sportsmen" << endl;

cout << " [6] Exit" << endl;

cout << "=========================" << endl;

cout << "Your choice : ";

//Вводим выбранный пользователем пункт меню

cin >> UserChoise;

//С помощью конструкции выбора анализируем этот выбор

//и осуществляем соответствующие действия

switch (UserChoise)

{

//Добавление новой записи о спортсмене в массив

case 1:

InputSportsman(Man);

AddSportsman(SportsmenArray, SportsmenCount, Man);

break;

//Удаление записи о спортсмене с указанным индексом из массива

case 2:

cout << endl << "Enter index of sportsman to delete : ";

//Вводим индекс удаляемого элемента-записи

cin >> RemovingIndex;

//Удаляем элемент. Если результат удаления ложь, то

if (!RemoveSportsman(SportsmenArray, SportsmenCount, RemovingIndex))

{

//Выдаем ошибку

cout << endl << "Invalid index! Try again." << endl;

}

break;

//Поиск всех записей о спорстменах, имеющих указанную фамилию

case 3:

cout << endl << "Enter surname for search : ";

//Вводим символ перевода строки

cin.get();

//Вводим фамилию для поиска

cin.getline(KeySurname, sizeof KeySurname);

//Вызываем функцию поиска и вывода найденных элементов

SearchAndPrintSportsmen(SportsmenArray, SportsmenCount, KeySurname);

break;

//Сортировка всех записей о спортсменах в порядке не возрастания

//количества сыгранных игр

case 4:

SortSportsmenByGamesCount(SportsmenArray, SportsmenCount);

break;

//Печать всех записей о спортсменах

case 5:

PrintAllSportsmen(SportsmenArray, SportsmenCount);

break;

//Выход

case 6:

cout << "Bye-bye..." << endl;

break;

//Ошибка, пользователь выбрал несуществующий пункт меню

default:

cout << endl << "Invalid choice! Try again." << endl;

}

//цикл выполняется до тех пор, пока пользователь не выберет выход

} while (UserChoise != 6);

}

int main()

{

//Описание массива записей (структур) о спортсменах

Sportsman SportsmenArray[MAX_SPORTSMEN_COUNT];

//Переменная для хранения количества записей в массиве

int SportsmenCount = 0;

//Загружаем все записи из файла

LoadFromFile(SportsmenArray, SportsmenCount, FILE_NAME);

//Выдаем меню и осуществляем операции

MainMenu(SportsmenArray, SportsmenCount);

//Перед выходом из программы сохраняем все записи в файл

SaveToFile(SportsmenArray, SportsmenCount, FILE_NAME);

return 0;

}