Разработка программы для создания и работы с двусвязным списком, состоящим из структур. (Структура содержит фамилию и год рождения), страница 3

Диаграмма взаимодействия функций для команды «добавить новый элемент в конец списка»:

Диаграмма взаимодействия функций для команды «добавить новый элемент в соответствии с сортировкой списка»:

Диаграмма взаимодействия функций для команды «сортировать список»:

Диаграмма взаимодействия функций для команды «выход»:


4.  Исходный код

4.1.  Листинг модуля ‘main.c’ – интерфейс взаимодействия с пользователем

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <time.h>

#include <ctype.h>

#include "LList.h"

// команды главного меню

#define CMD_CREATELIST      '0'

#define CMD_VIEWLIST        '1'

#define CMD_ADDNEWITEM      '2'

#define CMD_ADDNEWITEMSORT  '3'

#define CMD_SORTLIST        '4'

#define CMD_EXIT            '5'

// данные для генерации первоначального списка - фамилии

#define MAX_NAMELEN     15

#define MAX_NAMES       7

const char LastNames[MAX_NAMES][MAX_NAMELEN] =

{

    {"Ivanov"},

    {"Petrov"},

    {"Smirnoff"},

    {"Smith"},

    {"Krupskaya"},

    {"Bush"},

    {"Lermontov"}

};

// структура данных для хранения персональной информации

typedef struct Personal

{

    char       *LastName;

    struct tm   birthDate;

} PersonalData;

void    GenerateList(LL_LinkedList **list);

void    OutputList(LL_LinkedList *list);

void    AddNewItem(LL_LinkedList *list);

void    AddNewItemInSortingOrder(LL_LinkedList *list, LL_SortOreder order);

void    SortList(LL_LinkedList *list, LL_SortOreder *order);

boolean InputPersonalData(PersonalData *info);

boolean InputDate(struct tm *date);

int     CompareLastNames_cb(const void* data1, const void* data2);

void    FreePersonalData_cb(const void* userData);

// entry point

int main()

{

    char cmd;

    LL_LinkedList *list = NULL;

    LL_SortOreder order = LL_SORT_NOTSORTED;

    //установить стартовое значение генератора случайных чисел

    srand((unsigned)time(NULL));

    do

    {

        system("cls");

        puts("0 - Create linked list");

        puts("1 - View list content");

        puts("2 - Add new item at the end of list");

        puts("3 - Add new item according to sorting order of list");

        puts("4 - Sort the list");

        puts("5 - Exit");

        printf("\nChoose command: ");

        cmd = getch();

        switch (cmd)

        {

        case '0':

            GenerateList(&list);  //создание списка и генерация данных

            break;

        case '1':

            OutputList(list);    //вывод данных списка на экран

            break;

        case '2':

            AddNewItem(list);    //добавление нового элемента в конец списка

            order = LL_SORT_NOTSORTED;  //установка флага – список не отсортирован

            break;

        case '3':

            //добавление нового элемента в соответствии с сортировкой списка

            AddNewItemInSortingOrder(list, order);

            break;

        case '4':

            SortList(list, &order); //добавление нового элемента в соответствии с сортировкой списка

            break;

        }

    } while (CMD_EXIT != cmd);

    LL_RemoveAll(&list, FALSE);   //очистка памяти – удаление связного списка

    return 0;

}

/*====================================================================================

* Создать новый список и сгенерировать данные для него при помощи генератора

* случайных чисел.

*===================================================================================*/

void GenerateList(LL_LinkedList **list)

{

    int           listSize   = 0;

    int           nLastName  = 0;

    int           i          = 0;

    PersonalData *info;

    //вывести заглавие формы

    system("cls");

    puts("*** Create linked list ***\n\n");

    //проверка входных данных

    if (NULL == list || NULL != *list)

    {

        // *list – должен равняться NULL, для исключения утечки памяти

        puts("ERROR: wrong entry data");

        WaitAnyKey();

        return;

    }

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

    printf("Set list size: ");

    scanf("%d", &listSize);

    //проверка размера списка на корректность

    if (listSize < 3 || listSize > 99)

    {

        listSize = 3;

        puts("Value gets out from bounds (3-99). It was set to 3 (by default).");

    }

    //-------------------------------------------------------------------------

    //создание списка  

    LL_Create(list);

    //подписка на нотификацию об удалении элемента

    LL_SubscribeOnItemRemovingNotification(*list, FreePersonalData_cb);

    //подписка на нотификацию о сортировке

    LL_SubscribeOnSortNotification(*list, CompareLastNames_cb);

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

    for (i = 0; i < listSize; i++)

    {

        //выделение памяти для новых данных

        info = (PersonalData*)malloc(sizeof(PersonalData));

        memset((void*)info, 0, sizeof(PersonalData));        //обнуление области памяти

        //генерировать индекс фамилии, генерировать дату рождения

        nLastName = (int)((double)rand() / (RAND_MAX + 1) * (MAX_NAMES - 0) + 0);                  

        info->birthDate.tm_mday = (int)((double)rand() / (RAND_MAX + 1) * (29 - 1) + 1);            

        info->birthDate.tm_mon = (int)((double)rand() / (RAND_MAX + 1) * (12 - 0) + 0);            

        info->birthDate.tm_year = (int)((double)rand() / (RAND_MAX + 1) * (109 - 70) + 70);        

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

        info->LastName = (char*)malloc(sizeof(char) * (strlen(LastNames[nLastName]) + 1));

        strcpy(info->LastName, LastNames[nLastName]);