Разработка программы сложной структуры методом нисходящего программирования

Описание:
Доступные действия
Введите защитный код для скачивания файла и нажмите "Скачать файл"
Защитный код
Введите защитный код

Нажмите на изображение для генерации защитного кода

Текст:

Министерство образования Российской Федерации

Пензенский государственный университет

Кафедра «Вычислительная техника»

 

ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовой работе

по курсу «Программирование»

на тему «Разработка программы сложной структуры методом нисходящего программирования»

 

Выполнил:

      студент группы 13ВВ2

      Второв С. А.

Приняла:

      Коннова Л.Г.

 

Пенза 2014

 
 



Содержание

Введение  3

Постановка задачи   4

Выбор решения  5

Определение необходимых модулей программы. 5

Определение структуры файла базы данных. 7

Описание разработки программы    8

Отладка и тестирование  11

Описание программы    12

Разработка приложения database.exe. 12

Разработка меню    15

Разработка функции на языке Assembler  17

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

Заключение  26

Список используемых источников   27

Приложение А   28

Листинг программы.. 28

Файл «my.h». 28

Файл «main.c». 29

Файл «data.c». 29

Файл «mainmenu.c». 45

Файл «submenu.c». 48

Файл «dialog.c». 50

Файл «message.c». 52

Файл «sort.c». 54

Приложение B   56

Снимки экрана. 56

Заставка. 56

Главное меню.. 57

Меню сортировки.. 58

Таблица товаров. 59

Приложение С   60

Результат работы программы.. 60

Файл data.txt: 60


Введение

Все, что не так давно называли сведениями, фактами, данными, известиями, теперь называют одним общим словом «информация». Информация - это все фиксированные сообщения: книги, газеты, журналы, фотографии, фильмы, магнитные записи, записи на пластинах, каталоги, реклама, отчеты, письма и т. д.

Надо ли подчеркивать, сколь велик ее объем? И сколь сложен процесс поиска, накопления, обработки и передачи информации? А находить, накапливать, обрабатывать и передавать информацию нужно всюду.

Хранение информации - процесс не менее древний, нежели жизнь человеческой цивилизации. В самые древние времена ее хранил и передавал из поколения в поколение человек - его интеллект, его опыт. Хранение и передача информации зависит от ее носителя. Машинная технология обработки информации основана на новых носителях, на которых записывают данные для хранения в памяти машин. В хранящиеся в памяти машины сведения называют базами данных, и. информационными массивами, а для их обработки используют информационно-поисковые системы.

База данных – это организованная структура, предназначенная для хранения информации. С понятием базы данных тесно связано понятие системы управления базой данных. Это комплекс программных средств, предназначенных для создания структуры новой базы, наполнение её содержимым, редактирования содержимого и визуализации информации.

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

Целью моей курсовой работы является разработка базы данных «Оптовая база», предназначенной для выполнения различных операций с ее содержимым.


Постановка задачи

Необходимо разработать программу – базу данных «Оптовая база». Данные по базе включают следующие поля: название товара, код товара, количество товаров на складе и стоимость единицы товара.

Программа должна выполнять функции создания, удаления и сохранения базы данных. Так же добавлять, удалять и редактировать записи, осуществлять поиск и сортировку элементов по признаку.

Обязательные требования к программе:

1.     Многомодульность программы. Необходимо поделить программу на логические модули. Это улучшит восприятие исходного кода программы, упростит возможность редактирования программы и исправления возникающих ошибок при отладке или тестировании программы.

2.     Использование сложных типов данных – массивов, структур, файлов. Необходимо изучить базовые и сложные типы данных. Это необходимо для структуризации программы и обработки данных в исходном коде программы. Работа с файлами нужна для возможности сохранения базы данных в файл и считывания данных из файла.

3.     Режим работы видеосистемы - программа должна работать в текстовом или графическом режиме. Необходимо определиться с типом интерфейса, элементами управления и механизмом его работы. Далее разработать алгоритм для навигации пользователя по базе данных.

4.     Устройство ввода информации – клавиатура или мышь. Необходимо обрабатывать события с клавиатуры. Эти события нужно идентифицировать в зависимости от действий пользователя.

5.     Пользовательский интерфейс должен быть построен на основе меню и панели инструментов. Требуется выбрать подходящий вид и набор пунктов в меню. Это необходимо для создания удобного и понятного интерфейса.

6.     Наличие заставки. Заставка необходима для сообщения пользователю достаточной информации о программе.

7.     Операционная система - Microsoft Windows.

8.     Среда программирования - Microsoft Visual Studio.

9.     Язык программирования – Си и Ассемблер.


Выбор решения Определение необходимых модулей программы.

Разработанная программа состоит из следующих модулей:

1.     my.h

2.     main.c

3.     data.c

4.     mainmenu.c

5.     submenu.c

6.     dialog.c

7.     message.c

8.     sort.c

Библиотека my.h необходима для объявления глобальных переменных и функций. Представляет собой набор функций для: навигации, работы с базой, работы с записями, работы с файлом и многие другие.

Модуль main.c является основным модулем программы. Содержит в себе команды вызова двух функций – настройки размерности окна и вывода заставки.

Модуль data.c содержит в себеописание полей структуры односвязного списка и других переменных. Так же включает в себя все функции для работы с базой данных, записями и файлом.

Модуль mainmenu.c состоит из трех функций, предназначенных для работы с главным меню программы. Выбор пункта меню происходит при помощи клавиатуры (стрелки вверх/вниз), во время выбора обновляется положение маркера. При нажатии клавиши ввода в зависимости от номера выбранного пункта функция выполняет нужное действие.

Модуль submenu.c содержит функции для работы с подменю. Работа модуля аналогична функциям главного меню. Переключение между пунктами происходит при помощи клавиатуры (стрелки вправо/влево), выбор пункта с помощью кнопки ввода.

Модуль dialog.c предназначен для запроса о выборе двух действий. В главную функцию подается 3 параметра – вывод сообщения, текст первой кнопки и текст второй кнопки.

Модуль message.c включает в себя функции для вывода информации на экран. В главную функцию подается 3 сообщения, которые выводятся в специальной рамке. Так же содержит функции для вывода заставки и информации о программе.

Модуль sort.c служит для выбора критерия сортировки записей. Принцип работы аналогичен главному меню.


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

Записи отображаются в виде таблицы из пяти столбцов: порядковый номер товара в таблице, название товара, код товара, количество товаров на складе и стоимость единицы товара. Над таблицей есть подменю, которое включает в себя: возврат в главное меню, добавление, удаление, редактирование, поиск и сортировку записей.

Программа использует функции из библиотеки my.h, которые содержатся в модулях. Тем самым выполняется требование многомодульности курсовой работы.

 


Определение структуры файла базы данных.

Для структурирования данных внутри файла была выбрана следующая структура данных:

struct OPT {        

    char title[40];          

    char code[10];      

    unsigned long store;

    unsigned long cost; 

    struct OPT *next;       

};

База данных реализована в виде списка. Программа может выполнять следующие действия:

1.                          Создавать базу данных.

2.                          Сохранять базу данных в файл.

3.                          Открывать базу данных из файла.

4.                          Удалять файл базы данных.

5.                          Добавлять записи в базу данных.

6.                          Редактировать запись в базе данных.

7.                          Удалять запись из базы данных.

8.                          Удалять всю базу данных.

9.                          Осуществлять поиск по базе данных.

10.                      Производить сортировку записей базы данных по различным полям (по возрастанию/убыванию).

11.                      Выводить на экран записи базы данных.

На рисунке 2 представлена схема данных:

 


Описание разработки программы

Для создания этой программы был использован язык программирования Си. Этот язык является распространенным языком программирования. Си обеспечивает возможности структурирования данных.  Он позволяет разрабатывать большие, но структурированные программы, предоставляя возможность отдельной разработки подпрограмм. В качестве среды программирования был выбран программный продукт Visual Studio 2005.

Интерфейс программы представлен в виде меню, так как такой интерфейс является наиболее удобным и обеспечивает наименьшее время доступа к данным. Перемещение по пунктам меню может осуществляться с помощью клавиш клавиатуры.

При запуске программы на экран выводится заставка, содержащая минимально необходимую информацию о программе. При нажатии любой клавиши выводится главное меню, маркер которого изменяет свое положение при помощи стрелок (вверх/вниз). При нажатии клавиши ввода вызывается нужная функция.

В главном меню существуют пункты для работы со всей базой – ввод данных («Enter Data»), удаление данных («Delete Data»), просмотр всех файлов («View Data»). Так же для работы с файлом – считать данные из файла («Open File»), сохранить файл («Save File»), удалить файл («Delete File»).

Кроме работы с базой и файлом, в главном меню существуют еще несколько функций. Например, можно посмотреть некоторую информацию о программе (пункт «About») или посмотреть на заставку (пункт «Look Intro»). При выходе из программы (если есть хотя бы одна запись в памяти) появляется окно с запросом на сохранение файла.

При возникновении каких-либо ошибок на экран выдается сообщение (Файл отсутствует или база пуста). Если база существует (Пользователь открыл файл или ввел все записи с клавиатуры), то можно просмотреть все записи при помощи пункта меню «View Data».

Записи отображаются в виде таблицы. Над таблицей есть подменю, которое помимо возврата в главное меню включает в себя множество операций по работе с записями.

Можно добавить запись (пункт «Add») в готовую базу данных, при этом она поместиться в конец таблицы.

За удаление записи отвечает пункт «Remove». Нужно ввести порядковый номер удаляемой строки. Предусмотрена проверка на корректность ввода индекса (вводимое число положительное, не более текущего количества записей).

Если необходимо изменить строку в таблице, есть пункт «Edit». Вводимое число так же проверяется на корректность ввода.

Осуществлять поиск можно выбрав пункт «Find». Сначала появится запрос на выбор поля, по которому будет осуществляться поиск - название товара («Name») или код товара («Code»). Далее пользователь вводит критерий поиска. При успешном поиске выводится таблица, в которой выведена одна или несколько записей с данным критерием поиска.

При помощи пункта «Sort» можно сортировать данные. Сначала пользователь выбирает поле, по которому будет произведена сортировка, затем выбирает тип сортировки (возрастанию («Ascending») или убыванию («Descending»)).

Разработка программы началась с реализации вывода заставки, в которой при помощи символов было выведено название базы данных и краткое описание программы внутри рамки. Было создано главное меню, которое реагирует на нажатие клавиш (стрелки вверх/вниз, ввод). После этого были созданы функции inputdata() и viewdata(), позволяющие вводить записи и выводить данные на экран при помощи таблицы.

Затем началась разработка второго меню для работы с записями (подменю над таблицей). Были созданы функции removerecord(),  editrecord() и findrecord() для удаления, редактирования и поиска записи. Для сортировки записей (sortdata()) было разработано небольшое меню (sorttag()), в котором выбирается критерий сортировки для передачи в функцию сортировки (makesort()).

В итоге, после написания всех функций для работы с данными началась разработка функций для работы с файлом. Функции позволяют сохранять записи в файл (savefile()). Данные записываются в файле data.txt. Первая строчка – количество файлов, остальные – записи. Разделителем между полями служит символ (*). Так же существуют функции считывания из файла (openfile()) и удаления файла (deletefile()).

Программа начинается выполнением функции main. В этой функции вызываются функция заставки, из которой можно попасть в главное меню.

Как только пользователь нажмет на любую клавишу клавиатуры, появится главное меню (mmenu()). Выбор пункта меню происходит при помощи цикла с пост-условием, до тех пор, пока пользователь не нажмет кнопку ввода. Управление маркером меню происходит при помощи стрелок вверх/вниз. Порядковый номер выбранного пункта передается как параметр к функции, которая обновляет меню (updatemm()). После того, как пользователь выбрал нужный пункт (был нажат ввод), порядковый номер передается в функцию, которая, при помощи оператора switch выбирает нужное действие и выполняет его (makemm()).


Алгоритм работы главного меню представлен на рисунке 3.

 


Отладка и тестирование

В качестве среды разработки был выбран программный продукт Microsoft Visual Studio 2005. Программа предоставляет все средства, необходимые для разработки программы и ее отладки. Для отладки использовались такие инструменты, как точка останова, выполнение программы по шагам, анализ содержимого переменных.

Тестирование проводилось в процессе создания функций программы и после завершения разработки всей программы. В ходе тестирования была было исправлено множество проблем, связанных с выполнением некоторых действий. Необходимо продумать каждое возможное действие, которое может совершить пользователь. При появлении ошибки нужно вывести соответствующее оповещение (Файл не найден, База данных не содержит элементов). Так же требуется продумать типы данных и проверку вводимых элементов в базу – для строк (stest()) и чисел (ntest()). Нужно учитывать ввод номера строки в базе (функции для удаления и редактирования записи) – вводимое число должно быть положительным и не превосходящим количество строк в текущей базе данных.

Описание программы Разработка приложения database.exe

Разработанная программа состоит из нескольких модулей. Такое разбиение позволяет более эффективно работать с кодом программы, быстрее находить и исправлять возникшие ошибки.

Приложение database.exe - основной модуль программы. Для реализации навигации по главному меню был разработан модуль mainmenu.c. В нем описаны функций, необходимые для работы меню, вывода его на экран и выполнения выбранного действия.

Так же существуют другие элементы интерфейса, такие как подменю, вывод информационного сообщения и диалогового окна. Для работы с записями и файлом был разработан модуль data.c


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

 





Разработка меню

Навигация по программе состоит из главного меню и подменю.

Главное меню реализовано в модуле mainmenu.c и состоит из девяти пунктов: «Open File», «Save File», «Delete File», «View Data», «Enter Data», «Delete Data», «Look Intro», «About» и «Exit».

Меню реагирует на нажатие клавиш (стрелки вверх/вниз), тем самым в главной функции меню (mmenu()) происходит нахождение выбранного пункта и обновление меню (updatemm()). При нажатии кнопки ввода порядковый номер пункта меню передается в функцию, которая осуществляет выполнение выбранного действия (makemm()). Меню располагается посередине окна программы.

Помимо главного меню существует подменю, предназначенное для работы с записями. Оно описано в модуле submenu.c и состоит из шести пунктов: «Main Menu», «Add», «Remove», «Edit», «Find», «Sort». Алгоритм работы подменю аналогичен главному меню. Меню располагается в самом верху окна, под которым выводится таблица с имеющимися записями.


Ниже, в качестве примера, представлена таблица, которая описывает пункты главного меню.

Клавиша, вызывающая событие

Событие

Действия программы

Функция

Стрелка вверх/вниз, ввод

Открыть файл

Производится считывание данных из файла «data.txt» в список. Создается новый файл, либо перезаписывается старый.

openfile()

Сохранить файл

Данные записываются в файл «data.txt».

savefile()

Удалить файл

Файл «data.txt» полностью удаляется.

deletefile()

Просмотреть данные

Вывод записей из списка на экран в виде таблицы.

viewdata()

Ввести данные

Записи вводятся с клавиатуры. После ввода каждой записи появляется запрос на добавление новой записи.

inputdata()

Удалить данные

Все данные из списка удаляются.

deletedata()

Показать заставку

Просмотреть приветствие.

intro()

О программе

Некоторая информация о базе данных.

about()

Выход

При наличии хотя бы одной записи появляется запрос на сохранение базы в файл.

exit()

Таблица 1 – Пункты главного меню


Разработка функции на языке Assembler

Как известно, функции, реализованные на языке «Ассемблер», работают быстрее. Компилятор, входящий в состав среды разработки VS2005, позволяет это реализовать.

 Описание функции выполнено на языке Си, а тело функции представляет собой ассемблерную вставку. Для этого перед ассемблерной вставкой необходимо написать ключевое слово «__asm» и внутри фигурных скобок описать тело функции.

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

Для реализации ассемблерной вставки были использованы следующие инструкции:

1.     инструкция mov выполняет копирование содержимого источника в приемник;

2.     инструкция sub выполняет вычитание содержимого источника и приемника;

3.     инструкция cmp выполняет сравнение двух операндов и изменяет состояние флагов;

4.     инструкция je выполняет условный переход на метку, если операнды при выполнении инструкции cmp были равны;

5.     инструкция jmp выполняет безусловный переход на метку;

В результате был заменен следующий фрагмент кода программы:

pos = pos - 1;  

if(pos == 0)

pos = line;

Ассемблерная вставка:

               __asm {

            mov al, pos;

             mov bl, line;

             sub al, 1;                               

cmp al, 0;  

             je equally;         

             jmp assignment;     

             equally:

                 mov al, bl;     

             assignment:                                       

mov pos, al;

        }


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

Программа предназначена для хранения информации о некоторых товарах. В базе имеются такие поля, как название товара, код товара, количество товаров на складе и стоимость единицы товара.

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

При запуске программы на экран выводится заставка. С помощью символов было выведено название базы данных и краткая информация о программе.

 



После нажатия любой клавиши программа выводит главное меню. Переход от одного пункта к другому осуществляется при помощи клавиатуры  (стрелка вверх/вниз). Выбор пункта осуществляется нажатием кнопки ввода.

Главное меню состоит из следующих пунктов:

1.     Открытие файла

2.     Сохранение файла

3.     Удаление файла

4.     Просмотр данных

5.     Ввод данных

6.     Удаление всех данных

7.     Просмотр заставки

8.     О программе

9.     Выход

 



При возникновении каких-либо ошибок программа выводит оповещение. Например, если файл не найден. Если база данных пуста, то на экран выводится соответствующее информационное сообщение:

 


Если база данных содержит записи (или одну запись), то при выходе программа выводит диалоговое окно с запросом на сохранение файла:



При успешном открытии файла или после ввода записей на экране можно увидеть таблицу из пяти столбцов: порядковый номер товара, название товара, код товара, количество товаров на складе и стоимость единицы товара.

Над таблицей есть подменю, которое включает в себя: возврат в главное меню, добавление, удаление, редактирование, поиск и сортировку записей.

 Переход от одного пункта к другому осуществляется при помощи клавиатуры  (стрелка вправо/влево). Выбор пункта осуществляется нажатием кнопки ввода.



Добавить запись можно не только из главного меню, но и из подменю. Данные вводятся с клавиатуры. Существует 2 строковых поля и 2 числовых поля. Для ввода каждого из них существуют проверки на корректность ввода.

Для поля «Title» существует несколько проверок, таких как проверка на повторение одинакового названия, длину названия (30 символов) и проверка на содержание специального символа. Символ «*» существует как разделитель между столбцами в файле data.txt, следовательно он недопустим в полях базы данных. Для поля «Code» алгоритм аналогичный, но максимальная длина ограничивается до 6 символов.

Поля «Number» и «Cost» целочисленные, проверка ограничивается лишь диапазоном вводимых чисел (от 0 до 999999), так как эти поля не могут быть отрицательными.

При срабатывании функции проверки (было введено нежелательное значение) программа запрашивает ввод этого поля снова.



При удалении или редактировании записи программа запрашивает порядковый номер строки таблицы, которую нужно удалить/отредактировать. Существует ограничение на вводимое число. Оно должно быть больше нуля, так как нумерация начинается с единицы, еще оно должно быть не больше значения количества записей в таблице. Иначе выбираемой записи просто не будет существовать. При неправильном вводе экран очищается и запрос появляется снова.

Для поиска нужной строки необходимо выбрать пункт «Find». Затем появится диалоговое окно, запрашивающее выбрать поле, по которому осуществляется поиск (По названию, либо по коду товара).

Затем, если найдена запись (или несколько), то результат будет выведен в виде той же таблицы со строкой или несколькими строками, по которым происходил поиск по вводимому критерию. При нажатии любой клавиши таблица вернет свой исходный вид (Будет показано подменю и исходная таблица).

Ниже представлен результат поиска по критерию «Notebook». В названиях товара было найдено 3 совпадения, которые выведены на экран.


При выборе пункта подменю «Sort» происходит сортировка всех записей с указанными параметрами. В начале необходимо указать, по какому критерию осуществлять сортировку. Для этого было реализовано небольшое меню:

 


Затем необходимо определить тип сортировки (по возрастанию/убыванию):

 


Последнее, что необходимо выбрать – сохранять результат сортировки в память или нет. При сохранении результатов положение строк относительно друг друга изменится, и можно будет работать с ними в отсортированном виде. Но так же можно просто посмотреть на результат сортировки в виде таблицы и после нажатия любой клавиши строки вернуться в исходное положение.



Ниже представлен результат сортировки таблицы по цене в порядке убывания. Результат выводится на экран и ожидается нажатие клавиши.

 


Запрос на сохранение файла происходит либо при выходе из программы, либо при выборе пункта «Save File» в главном меню. Если база данных пуста, это окно выводится не будет.



Заключение

При выполнении данной курсовой работы были получены навыки разработки многомодульных программ. Были освоены приему создания пользовательского интерфейса, изучены функции работы с консолью, способы обработки событий с клавиатуры. Усвоены механизмы реализации меню. Изучены функции работы с файлами. Получены базовые навыки программирования на языке Си. Изучены основные возможности среды программирования Microsoft Visual Studio 2005. Получены навыки отладки и тестирования программ.

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

В дальнейшем программу можно улучшить путем добавления псевдографики. Можно оптимизировать код для более быстрого выполнения операций. Так же изменить работу алгоритмов, для более оптимального выполнения операций и добавить некоторые дополнительные функции.

Список используемых источников

1.     К. Поляков. «Программирование на языке Си (Глава IV.

Динамические структуры данных)».

2.     А. А. Вылиток. «Язык Си. Реализация списков с помощью цепочек

динамических объектов».

3.     MSDN.

4.     Свободная энциклопедия Википедия.


Приложение А Листинг программы Файл «my.h»

#define _CRT_SECURE_NO_WARNINGS       // Макрос для отключения предупреждений об устаревших функциях

#define _CRT_NONSTDC_NO_DEPRECATE      // Макрос для отключения предупреждений о "POSIX" функциях

#include

#include

#include

#include

#include

unsigned char i;        // Переменная для цикла

unsigned char key;      // Нажатая клавиша

unsigned char pos;      // Номер выбранной опции в меню

unsigned char line;     // Количество пунктов в меню    

void mmenu(); // Объявление функции показа главного меню

void updatemm(unsigned char pos); // Объявление функции обновления главного меню

void makemm(unsigned char pos);// Объявление функции выполнения выбранной опции в главном меню

void smenu(); // Объявление функции показа подменю

void updatesm(unsigned char pos); // Объявление функции обновления подменю

void makesm(unsigned char pos);  // Объявление функции выполнения выбранной опции в подменю

void intro(); // Объявление функции вывода заставки на экран

void about(); // Объявление функции показа информации о программе

unsigned char dialog(char message[30], char button1[20], char button2[20]);

void updatedialog(char message[30], char button1[20], char button2[20], unsigned char pos);    

void report(char line1[50], char line2[50], char line3[50]); 

long datasize();   // Объявление функции нахождения количества записей

unsigned char stest(char pstest[40], unsigned char pos);

unsigned char ntest(long pntest);

void openfile();   // Объявление функции открытия файла

void savefile();   // Объявление функции сохранения файла

void deletefile(); // Объявление функции удаления файла

void viewdata();   // Объявление функции просмотра всех записей

void inputdata();  // Объявление функции ввода данных

void deletedata(); // Объявление функции удаления данных

void editrecord();      // Объявление функции редактирования записи

void removerecord();    // Объявление функции удаления записи

void findrecord();      // Объявление функции поиска записи

void sortdata();        // Объявление функции сортировки

unsigned char sorttag();    

void sortupdate(unsigned char pos);  

void makesort(unsigned char tag, unsigned char stype);

Файл «main.c»

#include "my.h"    // Подключение библиотеки с функциями

void main() {

     system("mode con cols=78 lines=39");  // Настройка размерности окна

     intro();  // Вывод заставки

}

Файл «data.c»

#include "my.h"

struct OPT {                 // Оптовая база

    char title[40];              // Название товара

     char code[10];          // Код товара

     unsigned long store;    // Количество товаров

    unsigned long cost;      // Цена товара

     struct OPT *next;       // Указатель на следующий элемент

};

struct OPT *p = NULL;        // Указатель на данные

struct OPT *b = NULL;        // Указатель для операции копирования данных

struct OPT *copy = NULL;     // Указатель для операции копирования данных

struct OPT *first = NULL;    // Указатель на первую запись

struct OPT *last = NULL;     // Указатель на последнюю запись

char copytitle[40];

char copycode[10];

long copystore;

long copycost;

unsigned long j;   // Счетчик количества записей

unsigned long n;   // Количество записей в списке

long index;             // Индекс записи

FILE *fp; // Указатель на файл

long datasize() {  // Количество записей

     int count = 0;

     p = first;

     while(p != NULL){

          count++;

          p = p->next;

     }

     return count;

}

unsigned char stest(char pstest[40], unsigned char pos) {     // Проверка ввода поля строк

     unsigned char count = 1;     // Корректность (0/1)

     p = first;

     switch(pos) {

          case 1: { // Название товара

              if((strlen(pstest) > 30) || (strstr(pstest, "*") != NULL)) { 

                   count = 0;         // Максимальная размерность и специальный символ (*)

              } else {  // Проверка на повторение

                   while(p != NULL) {

                   if(strcmp(p->title, pstest) == 0)

                        count = 0;

                   p = p->next;

                   }

              }

              break;

          }

          case 2: { // Код товара

              if((strlen(pstest) > 6) || (strstr(pstest, "*") != NULL)) {  

                   count = 0;         // Максимальная размерность и специальный символ (*)

              } else {  // Проверка на повторение

                   while(p != NULL) {

                   if(strcmp(p->code, pstest) == 0)

                        count = 0;

                   p = p->next;

                   }

              }

              break;

          }

     }

     return count;

}

unsigned char ntest(long pntest) {    // Проверка ввода числа

     unsigned char count = 1;     // Корректность (0/1)

     if((pntest < 0) || (pntest > 999999)) // Положительное, до миллиона             

          count = 0;

     return count;

}

void openfile() {  // Открыть файл

     j = 0;    // Считчик количества строк

     if (fopen("data.txt", "r") == NULL) { // Если файла не существует

          report("File not found.",

              "Please enter the data.",

              "To return the main menu, press any key...");

          mmenu();      // Вернуться в главное меню 

     } else {

          deletedata(); // Очистка памяти

          fp = fopen("data.txt", "r"); // Открыть файл data.txt для чтения

          fscanf(fp, "%d ",  &j);     // Получение количества строк в файле

          // Заполнить первую запись

          p = (struct OPT*)(malloc(sizeof(struct OPT))); 

          fscanf(fp, "%[^*]*%[^*]*%d*%d ", p->title, p->code, &p->store, &p->cost);

          first = p;

          last = p;

          p->next = NULL;

          // Заполнить остальные записи

          for( ; j > 1; j--) {

              p = (struct OPT*)(malloc(sizeof(struct OPT)));

              fscanf(fp, "%[^*]*%[^*]*%d*%d ", p->title, p->code, &p->store, &p->cost);

              last->next = p;

              last = p;

              p->next = NULL;

          }

          fclose(fp);   // Закрыть файл

          smenu();  // Показать подменю

     }

}

void savefile() {  // Сохранить файл

     if(first != NULL) {     // Если есть хотя бы одна запись

          system("cls");

          if(dialog("Save the records in a file?", "Yes", "No") == 1) {

              // Открытие файла в режиме записи (Перезапись старого файла, если существует)

              fp = fopen("data.txt", "w");

              fprintf(fp, "%d ", datasize()); // Запись количества строк в первую строку файла

              p = first;

              while(p != NULL){

                   // Запись строк с использованием разделителей (* для колонок, для строк)

                   fprintf(fp, "%s*%s*%d*%d ",  p->title, p->code, p->store, p->cost);  

                   p = p->next;

              }

              fclose(fp);   // Закрыть файл

              report("Data save is successful.","","Press any key...");

          }

     }

}

void deletefile() {          // Удалить файл

     if (remove("data.txt") == 0) {        // Удалено успешно

          report("File delete is successful.","",

              "To return the main menu, press any key...");

     } else {

          fp = fopen("data.txt", "r");

          if(fp == NULL) {   // Файл не найден

              report("File not found.",

                   "Please enter the data.",

                   "To return the main menu, press any key...");

          } else {

              fclose(fp);        // Закрыть файл

              if (remove("data.txt") == -1) {       // Ошибка при удалении

                   report("Failed to delete file.",

                        "Please close the file.",

                        "To return the main menu, press any key...");

              }

          }

     }

     mmenu();  // Вернуться в главное меню 

}

void viewdata() {       // Просмотр записей

     printf(" %4c", 201);   // Вывод верхней границы таблицы

     for(i = 1; i <= 69; i++)

          printf("%c", 205);

     printf("%c %4c%8c%35c%9c%9c%9c", 187, 186, 186, 186, 186, 186, 186); 

     printf(" %4c   #%4c", 186, 186);          // Номер строки

     printf("              Title%16c", 186);         // Название товара     

     printf("  Code%3c", 186);                       // Код товара

     printf(" Number%2c", 186);                      // Количество товара

     printf("  Cost%3c", 186);                       // Цена товара

     printf(" %4c%8c%35c%9c%9c%9c", 186, 186, 186, 186, 186, 186);    

     j = 1;

     p = first;

     while (p != NULL) {          // Вывод строки таблицы

          printf(" %4c", 204);  

          for(i = 1; i <= 69; i++)

              printf("%c", 205);

          printf("%c %4c %-6d%c %-33s%c %-7s%c %-7lu%c %-7lu%c",

              185, 186, j, 186, p->title, 186, p->code, 186, p->store, 186, p->cost, 186);

          p = p->next;

          j++;

     }

     printf(" %4c", 200);   // Вывод нижней границы таблицы

     for(i = 1; i <= 69; i++)

          printf("%c", 205);

     printf("%c ", 188); 

}

void inputdata() {      // Ввод записей

     do { // Ввод записей по запросу

          system("cls"); // Очистка экрана после каждой введенной записи

          viewdata();   // Вывод уже введенных записей

          p = (struct OPT*)(malloc(sizeof(struct OPT)));

          b = p;

          do { // Проверка на повторение поля "Название товара"

              printf(" Title product: ");

              gets(copytitle);

          } while(stest(copytitle, 1) == 0);

          p = b;

          strcpy(p->title, copytitle);

          do { // Проверка на повторение поля "Код товара"

              printf(" Code product: ");

              gets(copycode);

          } while(stest(copycode, 2) == 0);

          p = b;

          strcpy(p->code, copycode);

          do { // Проверка ввода поля "Количество товаров"

              printf(" Number product: ");

              scanf("%ld", ©store);

              fflush(stdin);

          } while(ntest(copystore) == 0);

          p->store = copystore;

          do { // Проверка ввода поля "Цена товара"

              printf(" Cost product: ");

              scanf("%ld", ©cost);

              fflush(stdin);

          } while(ntest(copycost) == 0);

          p->cost = copycost;

          if(first == NULL) {          // Если вводится первая запись

              first = p;

              last = p;

              p->next = NULL;

          } else {                // Если имеется хотя бы одна запись

              last->next = p;

              last = p;

              p->next = NULL;

              }

     } while(dialog("Add a new record?", "Yes", "No") == 1);

     smenu();  // Показ подменю

}

void deletedata() {          // Удаление данных

     if(first != NULL) {

          p = first;

          b = p;

          while (p != NULL) {

              b = p->next;

              free(p);

              p = b;

          }

          p = NULL;

          b = NULL;

          first = NULL;

          last = NULL;

     }

}

void removerecord() {   // Удаление записи

     if(first == NULL) {          // Если нет записей

          report("Records not found.",

          "Please enter the data or to open the file.",

          "To return the main menu, press any key...");

          mmenu();      // Вернуться в главное меню 

     } else {  // Если имеется хотя бы одна запись

          if(datasize() == 1) {   // Если в таблице только одна запись

              first = NULL;

              last = NULL;

              smenu();

          } else {  // Если в таблице более одной записи

              do { // Проверка на коррекность ввода индекса записи

                   system("cls");

                   viewdata();  

                   printf(" Enter the index records: ");

                   scanf("%ld", &index);

                   fflush(stdin);

              } while((index <= 0) || (index > datasize()));                             

              p = first;

              b = NULL;

              j = 1;                      

              while(p != NULL) {           // Поиск адреса удаляемой записи

                   if(j == index) {   // Если текущий и удаляемый индексы совпали

                        b = p;

                   }

                   p = p->next;

                   j++;

              }

              if(b == first) {        // Если удаляемая строка первая

                   first = b->next;

              } else {                // Если удаляемая строка любая, кроме первой

                   p = first;

                   while((p != NULL) && (p->next != b)) // Поиск элемента перед удаляемым

                        p = p->next;

                   if(b == last) {         // Если удаляемая строка последняя

                        last = p;

                        p->next = NULL;

                   } else {           // Если удаляемая строка не первая и не последняя

                        p->next = b->next;

                   }

              }

          }

     }

     smenu();  // Показать  подменю

}

void editrecord() {     // Редактирование записи

     if(first == NULL) {          // Если нет записей

          report("Records not found.",

              "Please enter the data or to open the file.",

              "To return the main menu, press any key...");

          mmenu();      // Вернуться в главное меню 

     } else {           // Если имеется хотя бы одна запись

          do { // Проверка на коррекность ввода индекса записи

              system("cls");

              viewdata();  

              printf(" Enter the index records: ");

              scanf("%ld", &index);

              fflush(stdin);

          } while((index <= 0) || (index > datasize()));

          system("cls");

          viewdata();   // Вывод имеющихся записей

          do { // // Проверка на корректность ввода (перезапись всех полей) 

              printf(" Title product: ");

              gets(copytitle);

          } while(stest(copytitle, 1) == 0);

          do {

              printf(" Code product: ");

              gets(copycode);

          } while(stest(copycode, 2) == 0);

          do {

              printf(" Number product: ");

              scanf("%ld", ©store);

              fflush(stdin);

          } while(ntest(copystore) == 0);

          do {

              printf(" Cost product: ");

              scanf("%ld", ©cost);

              fflush(stdin);

          } while(ntest(copycost) == 0);

          p = first;

          j = 1;

          while(p != NULL) {      // Поиск адреса редактируемой записи

              if(j == index) {   // Если текущий и удаляемый индексы совпали

                   strcpy(p->title, copytitle);

                   strcpy(p->code, copycode);

                   p->store = copystore;

                   p->cost = copycost;

              }

              p = p->next;

              j++;

          }

     }

     smenu();  // Показать  подменю

}

void findrecord() {          // Поиск записи

     char search[30];   // Критерий поиска

     unsigned char f;   // Найдено ли совпадение (0/1)

     unsigned char by;  // Поле поиска

     system("cls");

     if(first == NULL) {          // Если нет записей, то вывести сообщение

          report("Records not found.",

              "Please enter the data or to open the file.",

              "To return the main menu, press any key...");

          mmenu();      // Вернуться в главное меню 

     } else {

          by = dialog("Search by...", "Name", "Code");    // Указать поле поиска

          system("cls");

          viewdata();  

          printf(" Search: ");   // Ввести критерий поиска

          gets(search);

          p = first;

          f = 0;

          switch(by) { 

              case 1:   {    // Название товара

                             while(p != NULL) { // Поиск запроса в названии товара   

                                 if (strstr(p->title, search) != NULL) {

                                      f = 1;

                                 }

                                 p = p->next;

                             }

                        }

              case 2:   {    // Код товара

                             while(p != NULL) { // Поиск запроса по коду товара 

                                 if (strstr(p->code, search) != NULL) {

                                      f = 1;   

                                 }

                                 p = p->next;

                             }

                        }

          }

          system("cls");

          if (f == 1) { // Если найдено хотя бы одно совпадение

              printf(" %4c", 201);  

              for(i = 1; i <= 69; i++)

                   printf("%c", 205);

              printf("%c %4c%8c%35c%9c%9c%9c", 187, 186, 186, 186, 186, 186, 186); 

              printf(" %4c   #%4c", 186, 186);          // Номер строки

              printf("              Title%16c", 186);         // Название товара     

              printf("  Code%3c", 186);                       // Код товара

              printf(" Number%2c", 186);                      // Количество товара

              printf("  Cost%3c", 186);                       // Цена товара

              printf(" %4c%8c%35c%9c%9c%9c", 186, 186, 186, 186, 186, 186);        

              j = 1;

              p = first;

              switch(by) { 

                   case 1:   {    // Название товара

                        while(p != NULL) {

                             if (strstr(p->title, search) != NULL) {    // Выводить найденные записи

                                 printf(" %4c", 204);  

                                 for(i = 1; i <= 69; i++)

                                      printf("%c", 205);

                                 printf("%c %4c %-6d%c %-33s%c %-7s%c %-7lu%c %-7lu%c",

                                      185, 186, j, 186, p->title, 186, p->code, 186, p->store, 186, p->cost, 186); 

                                 j++;

                             }

                             p = p->next;

                        }

                   }

                   case 2: { // Код товара

                        while(p != NULL) {

                             if (strstr(p->code, search) != NULL) {     // Выводить найденные записи

                                 printf(" %4c", 204);  

                                 for(i = 1; i <= 69; i++)

                                      printf("%c", 205);

                                 printf("%c %4c %-6d%c %-33s%c %-7s%c %-7d%c %-7d%c",

                                      185, 186, j, 186, p->title, 186, p->code, 186, p->store, 186, p->cost, 186); 

                                 j++;

                             }

                             p = p->next;

                        }

                   }

              }

              printf(" %4c", 200);  

              for(i = 1; i <= 69; i++)

                   printf("%c", 205);

              printf("%c ", 188);

              getch();

              smenu();  // Вернуться в подменю

          } else {  // Если не найдено совпадений

              report("Record not found.","",

                   "To return the submenu, press any key...");

              smenu();  // Показать  подменю

          }

     }

}

void sortdata() {  // Сортировать записи

     unsigned char tag;      // Параметр сортировки

     unsigned char stype;    // Тип сортировки

     n = datasize();   

     // Выделение памяти на массив структур на n элементов

     copy = (struct OPT*)(malloc(sizeof(struct OPT) * n));

     // Перевод из списка в массив структур

     j = 0;   

     p = first;

     while (p != NULL) {    

          strcpy(copy[j].title, p->title);

          strcpy(copy[j].code, p->code);

          copy[j].store = p->store;

          copy[j].cost = p->cost;

          p = p->next;

          j++;

     }

     tag = sorttag();   // Выбор критерия сортировки

     stype = dialog("Sort by...", "Ascending", "Descending"); // Тип сортировки

     makesort(tag, stype);   // Сортировка массива структур

     if(dialog("Save result sorting?", "Yes", "No") == 1) {   // Запрос на сохранение результата сортировки в список       

          j = 0;        // Перевод из массива структур в список

          p = first;

          while (p != NULL) {    

              strcpy(p->title, copy[j].title);

              strcpy(p->code, copy[j].code);

              p->store = copy[j].store;

              p->cost = copy[j].cost;

              p = p->next;

              j++;

          }

     } else {      // Показать результат сортировки

          system("cls");

          j = 0;

          printf(" %4c", 201);  

          for(i = 1; i <= 69; i++)

              printf("%c", 205);

          printf("%c %4c%8c%35c%9c%9c%9c", 187, 186, 186, 186, 186, 186, 186); 

          printf(" %4c   #%4c", 186, 186);          // Номер строки

          printf("              Title%16c", 186);         // Название товара     

          printf("  Code%3c", 186);                       // Код товара

          printf(" Number%2c", 186);                      // Количество товара

          printf("  Cost%3c", 186);                       // Цена товара

          printf(" %4c%8c%35c%9c%9c%9c", 186, 186, 186, 186, 186, 186);    

          for(j = 0; j < n; j++) {     // Вывод строки таблицы

              printf(" %4c", 204);  

              for(i = 1; i <= 69; i++)

                   printf("%c", 205);

              printf("%c %4c %-6d%c %-33s%c %-7s%c %-7lu%c %-7lu%c",

                   185, 186, j + 1, 186, copy[j].title, 186, copy[j].code, 186, copy[j].store, 186, copy[j].cost, 186);   

          }

          printf(" %4c", 200);  

          for(i = 1; i <= 69; i++)

              printf("%c", 205);

          printf("%c ", 188); 

          getch();

     }

     smenu();  // Показать  подменю

}

void makesort(unsigned char tag, unsigned char stype) {       // Сортировка массива структур

     char ctmp[40];

     unsigned long itmp;

     n = datasize();    // Количество записей в списке

     switch(tag) {

          case 1:   // Название товара

              {

                   switch(stype) {   

                        case 1:   // Сортировка по возрастанию

                             {

                                 // Сортировка массива структр по алфавиту "Название товара" (возрастание)

                                 for(i = 0 ; i < n ; i++) {

                                    for(j = 0 ; j < n - i - 1  ; j++) {    

                                         // Сравниваем два соседних элемента

                                         if(strcmp(copy[j].title, copy[j + 1].title) > 0) {

                                                // Перестановка поля "Название товара"

                                               strcpy(ctmp, copy[j].title);

                                                strcpy(copy[j].title, copy[j + 1].title);

                                                strcpy(copy[j + 1].title, ctmp);

                                                // Перестановка поля "Код товара"

                                                strcpy(ctmp, copy[j].code);

                                                strcpy(copy[j].code, copy[j + 1].code);

                                                strcpy(copy[j + 1].code, ctmp);

                                                // Перестановка поля "Количество товара"

                                                itmp = copy[j].store;

                                                copy[j].store = copy[j + 1].store;

                                                copy[j + 1].store = itmp;

                                               // Перестановка поля "Цена товара"

                                                itmp = copy[j].cost;

                                                copy[j].cost = copy[j + 1].cost;

                                                copy[j + 1].cost = itmp;

                                         }

                                      }

                                 }

                                 break;

                             }

                        case 2:   // Сортировка по убыванию

                             {

                                  // Сортировка массива структр по алфавиту "Название товара" (убывание)

                                 for(i = 0 ; i < n ; i++) {

                                    for(j = 0 ; j < n - i - 1  ; j++) {    

                                         // Сравниваем два соседних элемента

                                         if(strcmp(copy[j].title, copy[j + 1].title) < 0) {

                                                // Перестановка поля "Название товара"

                                               strcpy(ctmp, copy[j].title);

                                                strcpy(copy[j].title, copy[j + 1].title);

                                                strcpy(copy[j + 1].title, ctmp);

                                                // Перестановка поля "Код товара"

                                                strcpy(ctmp, copy[j].code);

                                                strcpy(copy[j].code, copy[j + 1].code);

                                                strcpy(copy[j + 1].code, ctmp);

                                                // Перестановка поля "Количество товара"

                                                itmp = copy[j].store;

                                                copy[j].store = copy[j + 1].store;

                                                copy[j + 1].store = itmp;

                                                // Перестановка поля "Цена товара"

                                                itmp = copy[j].cost;

                                                copy[j].cost = copy[j + 1].cost;

                                                copy[j + 1].cost = itmp;

                                         }

                                      }

                                 }

                                 break;

                             }

                   }

                   break;

              }

          case 2:   // Код товара

              {

                   switch(stype) {

                        case 1:   // Сортировка по возрастанию

                             {

                                 // Сортировка массива структр по алфавиту "Код товара" (возрастание)

                                 for(i = 0 ; i < n ; i++) {

                                    for(j = 0 ; j < n - i - 1  ; j++) {    

                                         // Сравниваем два соседних элемента

                                         if(strcmp(copy[j].code, copy[j + 1].code) > 0) {

                                                // Перестановка поля "Название товара"

                                               strcpy(ctmp, copy[j].title);

                                                strcpy(copy[j].title, copy[j + 1].title);

                                                strcpy(copy[j + 1].title, ctmp);

                                                // Перестановка поля "Код товара"

                                                strcpy(ctmp, copy[j].code);

                                                strcpy(copy[j].code, copy[j + 1].code);

                                                strcpy(copy[j + 1].code, ctmp);

                                                // Перестановка поля "Количество товара"

                                                itmp = copy[j].store;

                                                copy[j].store = copy[j + 1].store;

                                                copy[j + 1].store = itmp;

                                                // Перестановка поля "Цена товара"

                                                itmp = copy[j].cost;

                                                copy[j].cost = copy[j + 1].cost;

                                                copy[j + 1].cost = itmp;

                                         }

                                      }

                                 }

                                 break;

                             }

                        case 2:   // Сортировка по убыванию

                             {

                                 // Сортировка массива структр по алфавиту "Код товара" (убывание)

                                 for(i = 0 ; i < n ; i++) {

                                    for(j = 0 ; j < n - i - 1  ; j++) {    

                                         // Сравниваем два соседних элемента

                                         if(strcmp(copy[j].code, copy[j + 1].code) < 0) {

                                                // Перестановка поля "Название товара"

                                               strcpy(ctmp, copy[j].title);

                                                strcpy(copy[j].title, copy[j + 1].title);

                                                strcpy(copy[j + 1].title, ctmp);

                                                // Перестановка поля "Код товара"

                                                strcpy(ctmp, copy[j].code);

                                                strcpy(copy[j].code, copy[j + 1].code);

                                                strcpy(copy[j + 1].code, ctmp);

                                                // Перестановка поля "Количество товара"

                                                itmp = copy[j].store;

                                                copy[j].store = copy[j + 1].store;

                                                copy[j + 1].store = itmp;

                                                // Перестановка поля "Цена товара"

                                                itmp = copy[j].cost;

                                                copy[j].cost = copy[j + 1].cost;

                                                copy[j + 1].cost = itmp;

                                         }

                                      }

                                 }

                                 break;

                             }

                   }

                   break;

              }

          case 3:   // Количество товара

              {

                   switch(stype) {

                        case 1:   // Сортировка по возрастанию

                             {

                                 // Сортировка массива структр по возрастанию количества товаров

                                 for(i = 0 ; i < n ; i++) {

                                    for(j = 0 ; j < n - i - 1  ; j++) {    

                                         // Сравниваем два соседних элемента

                                         if(copy[j].store > copy[j + 1].store) {

                                                // Перестановка поля "Название товара"

                                               strcpy(ctmp, copy[j].title);

                                                strcpy(copy[j].title, copy[j + 1].title);

                                                strcpy(copy[j + 1].title, ctmp);

                                                // Перестановка поля "Код товара"

                                                strcpy(ctmp, copy[j].code);

                                                strcpy(copy[j].code, copy[j + 1].code);

                                                strcpy(copy[j + 1].code, ctmp);

                                                // Перестановка поля "Количество товара"

                                                itmp = copy[j].store;

                                                copy[j].store = copy[j + 1].store;

                                                copy[j + 1].store = itmp;

                                                // Перестановка поля "Цена товара"

                                                itmp = copy[j].cost;

                                                copy[j].cost = copy[j + 1].cost;

                                                copy[j + 1].cost = itmp;

                                         }

                                      }

                                 }

                                 break;

                             }

                        case 2:   // Сортировка по убыванию

                             {

                                 // Сортировка массива структр по убыванию количества товаров

                                 for(i = 0 ; i < n ; i++) {

                                    for(j = 0 ; j < n - i - 1  ; j++) {    

                                         // Сравниваем два соседних элемента

                                         if(copy[j].store < copy[j + 1].store) {

                                                // Перестановка поля "Название товара"

                                               strcpy(ctmp, copy[j].title);

                                                strcpy(copy[j].title, copy[j + 1].title);

                                                strcpy(copy[j + 1].title, ctmp);

                                                // Перестановка поля "Код товара"

                                                strcpy(ctmp, copy[j].code);

                                                strcpy(copy[j].code, copy[j + 1].code);

                                                strcpy(copy[j + 1].code, ctmp);

                                                // Перестановка поля "Количество товара"

                                                itmp = copy[j].store;

                                                copy[j].store = copy[j + 1].store;

                                                copy[j + 1].store = itmp;

                                                // Перестановка поля "Цена товара"

                                                itmp = copy[j].cost;

                                                copy[j].cost = copy[j + 1].cost;

                                                copy[j + 1].cost = itmp;

                                         }

                                      }

                                 }

                                 break;

                             }

                   }

                   break;

              }

          case 4:   // Цена товара

              {

                   switch(stype) {

                        case 1:   // Сортировка по возрастанию

                             {

                                 // Сортировка массива структр по возрастанию цены

                                 for(i = 0 ; i < n ; i++) {

                                    for(j = 0 ; j < n - i - 1  ; j++) {    

                                         // Сравниваем два соседних элемента

                                          if(copy[j].cost > copy[j + 1].cost) {

                                                // Перестановка поля "Название товара"

                                               strcpy(ctmp, copy[j].title);

                                                strcpy(copy[j].title, copy[j + 1].title);

                                                strcpy(copy[j + 1].title, ctmp);

                                                // Перестановка поля "Код товара"

                                                strcpy(ctmp, copy[j].code);

                                                strcpy(copy[j].code, copy[j + 1].code);

                                                strcpy(copy[j + 1].code, ctmp);

                                                // Перестановка поля "Количество товара"

                                                itmp = copy[j].store;

                                                copy[j].store = copy[j + 1].store;

                                                copy[j + 1].store = itmp;

                                                // Перестановка поля "Цена товара"

                                                itmp = copy[j].cost;

                                                copy[j].cost = copy[j + 1].cost;

                                                copy[j + 1].cost = itmp;

                                         }

                                      }

                                 }

                                 break;

                             }

                        case 2:   // Сортировка по убыванию

                             {

                                 // Сортировка массива структр по убыванию цены

                                 for(i = 0 ; i < n ; i++) {

                                    for(j = 0 ; j < n - i - 1  ; j++) {    

                                         // Сравниваем два соседних элемента

                                         if(copy[j].cost < copy[j + 1].cost) {

                                                // Перестановка поля "Название товара"

                                               strcpy(ctmp, copy[j].title);

                                                strcpy(copy[j].title, copy[j + 1].title);

                                                strcpy(copy[j + 1].title, ctmp);

                                                // Перестановка поля "Код товара"

                                                strcpy(ctmp, copy[j].code);

                                                strcpy(copy[j].code, copy[j + 1].code);

                                                strcpy(copy[j + 1].code, ctmp);

                                                // Перестановка поля "Количество товара"

                                                itmp = copy[j].store;

                                                copy[j].store = copy[j + 1].store;

                                                copy[j + 1].store = itmp;

                                                // Перестановка поля "Цена товара"

                                                itmp = copy[j].cost;

                                                copy[j].cost = copy[j + 1].cost;

                                                copy[j + 1].cost = itmp;

                                         }

                                      }

                                 }

                                 break;

                             }

                   }

                   break;

              }

     }

}

Файл «mainmenu.c»

#include "my.h"

void mmenu() { // Показ главного меню

     line = 9; // Количество строк в главном меню

     system("cls");

     pos = 1;

     updatemm(pos); // Обновление меню

     do {

          key = getch();

          switch(key) {

              case 72: {    // Нажата стрелка вверх

                        pos -= 1;

                        if(pos == 0)

                             pos = line;

                        updatemm(pos);

                        break;

                   }

              case 80: {    // Нажата стрелка вниз

                        pos += 1;

                        if(pos == (line + 1))

                             pos = 1;

                        updatemm(pos);

                        break;

                   }

              case 13: {    // Нажат ввод

                        key = 0;

                        break;

                   }

          }

     } while(key != 0);

     makemm(pos);  // Выполнение выбранной опции в главном меню

}

void updatemm(unsigned char pos) {    // Обновление главного меню

     system("cls");

     printf(" %25c", 201);

     for(i = 1; i <= 26; i++)

          printf("%c", 205);

     if(pos == 1) {

          printf("%c %25c     >> Open File         %c %25c", 187, 186, 186, 204);

     } else

          printf("%c %25c   Open File              %c %25c", 187, 186, 186, 204);

     for(i = 1; i <= 26; i++)

          printf("%c", 205);

     if(pos == 2) {

          printf("%c %25c     >> Save File         %c %25c", 185, 186, 186, 204);

     } else

          printf("%c %25c   Save File              %c %25c", 185, 186, 186, 204);

     for(i = 1; i <= 26; i++)

          printf("%c", 205);

     if(pos == 3) {

          printf("%c %25c     >> Delete File       %c %25c", 185, 186, 186, 204);

     } else

          printf("%c %25c   Delete File            %c %25c", 185, 186, 186, 204);

     for(i = 1; i <= 26; i++)

          printf("%c", 205);

     if(pos == 4) {

          printf("%c %25c     >> View Data         %c %25c", 185, 186, 186, 204);

     } else

          printf("%c %25c   View Data              %c %25c", 185, 186, 186, 204);

     for(i = 1; i <= 26; i++)

          printf("%c", 205);

     if(pos == 5) {

          printf("%c %25c     >> Enter Data        %c %25c", 185, 186, 186, 204);

     } else

          printf("%c %25c   Enter Data             %c %25c", 185, 186, 186, 204);

     for(i = 1; i <= 26; i++)

          printf("%c", 205);

     if(pos == 6) {

          printf("%c %25c     >> Delete Data       %c %25c", 185, 186, 186, 204);

     } else

          printf("%c %25c   Delete Data            %c %25c", 185, 186, 186, 204);       

     for(i = 1; i <= 26; i++)

          printf("%c", 205);

     if(pos == 7) {

          printf("%c %25c     >> Look Intro        %c %25c", 185, 186, 186, 204);

     } else

          printf("%c %25c   Look Intro             %c %25c", 185, 186, 186, 204);

     for(i = 1; i <= 26; i++)

          printf("%c", 205);

     if(pos == 8) {

          printf("%c %25c     >> About             %c %25c", 185, 186, 186, 204);

     } else

          printf("%c %25c   About                  %c %25c", 185, 186, 186, 204);

     for(i = 1; i <= 26; i++)

          printf("%c", 205);

     if(pos == 9) {

          printf("%c %25c     >> Exit              %c %25c", 185, 186, 186, 200);

     } else

          printf("%c %25c   Exit                   %c %25c", 185, 186, 186, 200);

     for(i = 1; i <= 26; i++)

          printf("%c", 205);

     printf("%c ", 188);   

}

void makemm(unsigned char pos) { // Выполнение выбранной опции в главном меню   

     switch(pos) {

          case 1:   {    // Открытие файла

                        openfile();  

                        break;

                   }

          case 2:   {    // Сохранение файла

                        if(datasize() == 0) {   // Если нет записей

                             report("Records not found.",

                                 "Please enter the data.",

                                 "To return the main menu, press any key...");

                        } else {

                             savefile();

                        }

                        mmenu();      // Вернуться в главное меню 

                        break;

                   }

          case 3:   {    // Удаление файла

                        deletefile();

                        break;

                   }

          case 4:   {    // Просмотр данных

                        if(datasize() == 0) {   // Если нет записей

                             report("Records not found.",

                                 "Please enter the data or to open the file.",

                                 "To return the main menu, press any key...");

                             mmenu();  // Вернуться в главное меню 

                        } else {

                             smenu();  // Показать подменю с записями       

                        }

                        break;

                   }

          case 5:   {    // Ввод данных

                        inputdata(); 

                        break;

                   }

          case 6:   {    // Удаление данных

                        if(datasize() == 0) {   // Если нет записей

                             report("Records not found.",

                                 "Please enter the data.",

                                 "To return the main menu, press any key...");

                        } else {

                             deletedata();

                             report("All data removed.","",

                             "To return the main menu, press any key...");

                        }

                        mmenu();      // Вернуться в главное меню     

                        break;

                   }

          case 7:   {    // Показать заставку

                        intro();

                        break;

                   }

          case 8:   {    // О программе

                        about();

                        break;

                   }

          case 9:   {    // Выход

                        savefile();        // Запрос на сохранение файла   

                        exit(0);

                        break;

                   }

     }

}

Файл «submenu.c»

#include "my.h"

void smenu() { // Показ подменю

     line = 6; // Количество строк в подменю

     system("cls");

     pos = 1;

     updatesm(pos); // Обновление подменю

     do {

          key = getch();

          switch(key) {

              case 75: {    // Нажата стрелка влево

                        pos--;   

                        if(pos == 0)

                             pos = line;

                        updatesm(pos);

                        break;

                   }

              case 77: {    // Нажата стрелка вправо

                        pos++;

                        if(pos == (line + 1))

                             pos = 1;

                        updatesm(pos);

                        break;

                   }

              case 13: {    // Нажат ввод

                        key = 0;

                        break;

                   }

          }

     } while(key != 0);

     makesm(pos);  // Выполнение выбранной опции в подменю   

}

void updatesm(unsigned char pos) {    // Обновление подменю

     char itemMenu[80];      // Главное меню

     char itemAdd[80];       // Добавить запись

     char itemRemove[80];    // Удалить запись

     char itemEdit[80];      // Редактировать запись

     char itemFind[80];      // Поиск записи

     char itemSort[80];      // Сортировка записей

     strcpy(itemMenu, "");

     strcpy(itemAdd, "");

     strcpy(itemRemove, "");

     strcpy(itemEdit, "");

     strcpy(itemFind, "");

     strcpy(itemSort, "");

     switch(pos) {      // Выбор позиции в подменю  

              case 1:   {    // Перейти в главное меню

                        strcpy(itemMenu, "+=============+-------------------------------------------------------+");

                        break;

                   }

              case 2:   {    // Добавить новую запись

                        strcpy(itemAdd, "+-------------+==========+--------------------------------------------+");

                        break;

                   }

              case 3:   {    // Удалить запись

                        strcpy(itemRemove, "+------------------------+==========+---------------------------------+");

                        break;

                   }

              case 4:   {    // Редактировать запись

                        strcpy(itemEdit, "+-----------------------------------+==========+----------------------+");

                        break;

                   }

              case 5:   {    // Найти запись

                        strcpy(itemFind, "+----------------------------------------------+==========+-----------+");

                        break;

                   }

              case 6:   {    // Сортировать записи

                        strcpy(itemSort, "+---------------------------------------------------------+===========+");

                        break;

                   }

          }

     system("cls");

     printf("    %s%s%s%s%s%s ", itemMenu, itemAdd, itemRemove, itemEdit, itemFind, itemSort);

     printf("   |  Main Menu  |   Add    |  Remove  |   Edit   |   Find   |   Sort    | ");

     printf("   %s%s%s%s%s%s ", itemMenu, itemAdd, itemRemove, itemEdit, itemFind, itemSort);

     viewdata();        // Вывод всех записей

}

void makesm(unsigned char pos) { // Выполнение выбранной опции в подменю

     switch(pos) {

          case 1:   {    // Вернутся в главное меню

                        mmenu(); 

                        break;

                   }

          case 2:   {    // Добавить новую запись

                        inputdata(); 

                        break;

                   }

          case 3:   {    // Удалить запись

                        removerecord();   

                        break;

                   }

          case 4:   {    // Редактировать запись

                        editrecord();

                        break;

                   }

          case 5:   {    // Искать запись

                        findrecord();

                        break;

                   }

          case 6:   {    // Сортировать записи

                        sortdata();  

                        break;

                   }

     }

}


Файл «dialog.c»

#include "my.h"

unsigned char dialog(char message[30], char button1[20], char button2[20]) {     // Окно диалога

     pos = 1;

     updatedialog(message, button1, button2, pos);   // Обновление окна

     do {

          key = getch();

          switch(key) {

              case 75: {    // Нажата стрелка влево

                        pos--;   

                        if(pos == 0)

                             pos = 2;

                        updatedialog(message, button1, button2, pos);  

                        break;

                   }

              case 77: {    // Нажата стрелка вправо

                        pos++;

                        if(pos == 3)

                             pos = 1;

                        updatedialog(message, button1, button2, pos);  

                        break;

                   }

              case 13: {    // Нажат ввод

                        key = 0;

                        break;

                   }

          }

     } while(key != 0);

     return pos;

}

void updatedialog(char message[30], char button1[20], char button2[20], unsigned char pos) {     // Обновление окна диалога

     system("cls");

     printf(" %21c", 201);

     for(i = 1; i <= 37; i++)

          printf("%c", 205);

     printf("%c", 187);

     printf(" %21c%38c", 186, 186);

     printf(" %21c%38c", 186, 186);

     printf(" %21c%33s%5c", 186, message, 186);         // Сообщение

     printf(" %21c%38c", 186, 186);

     printf(" %21c%38c", 186, 186);

     switch(pos) {

          case 1:       // Кнопка 1

              {

                   printf(" %21c%4c", 186, 201);

                   for(i = 1; i <= 12; i++)

                        printf("%c", 205);

                   printf("%c%21c %21c%4c%11s%2c%15s%6c %21c%4c",

                        187, 186, 186, 186, button1, 186, button2, 186, 186, 200);

                   for(i = 1; i <= 12; i++) {

                        printf("%c", 205);

                   }

                   printf("%c%21c", 188, 186);

                   break;

              }

          case 2:       // Кнопка 2

              {

                   printf(" %21c%21c", 186, 201);

                   for(i = 1; i <= 12; i++)

                        printf("%c", 205);

                   printf("%c%4c %21c%15s%6c%11s%2c%4c %21c%21c",

                        187, 186, 186, button1, 186, button2, 186, 186, 186, 200);

                   for(i = 1; i <= 12; i++)

                        printf("%c", 205);

                   printf("%c%4c", 188, 186);

                   break;

              }

     }

     printf(" %21c%38c %21c", 186, 186, 200);

     for(i = 1; i <= 37; i++)

          printf("%c", 205);

     printf("%c ", 188);

}

Файл «message.c»

#include "my.h"

void report(char line1[50], char line2[50], char line3[50]) { // Вывод сообщения

     system("cls");

     printf(" %16c", 201);

     for(i = 1; i <= 46; i++)

          printf("%c", 205);

     printf("%c %16c%47c %16c%44s%3c %16c%47c", 187, 186, 186, 186, line1, 186, 186, 186);

     printf(" %16c%44s%3c %16c%47c", 186, line2, 186, 186, 186);

     printf(" %16c%44s%3c %16c%47c %16c", 186, line3, 186, 186, 186, 200);

     for(i = 1; i <= 46; i++)

          printf("%c", 205);

     printf("%c ", 188);

     getch(); 

}

void about() { // Показ информации о программе

     system("cls");

     printf(" %16c", 201);

     for(i = 1; i <= 45; i++)

          printf("%c", 205);

     printf("%c %16c%46c", 187, 186, 186);

     printf(" %16c            "Wholesale" database.            %c %16c%46c", 186, 186, 186, 186);

     printf(" %16c    Records are stored in memory or file.    %c %16c%46c", 186, 186, 186, 186);

     printf(" %16c  To return the main menu, press any key...  %c", 186, 186);

     printf(" %16c%46c %16c", 186, 186, 200);

     for(i = 1; i <= 45; i++)

          printf("%c", 205);

     printf("%c ", 188);

     getch(); 

     mmenu();  // Вывод главного меню

}

void intro() { // Вывод заставки на экран

     printf("       ****    ********* *********    ****    *******        *          **** ");

     printf("    *      *  *       * *   *   *  *      *  *      *      * *       *    * ");

     printf("   *        * *       *     *     *        * *      *     *   *      *    * ");

     printf("   *        * *       *     *     *        * *******     *******       **** ");

     printf("   *        * *       *     *     *        * *      *   *       *     *   * ");

     printf("    *      *  *       *     *      *      *  *      *  *         *   *    * ");

     printf("      ****    *       *     *        ****    *******  *           * *     * ");

     printf("                    ########       #       #######       # ");

     printf("                    #      #      # #      #     #      # # ");

     printf("                    #            #   #           #     #   # ");

     printf("                    ########    #######    #######    ####### ");

     printf("                    #      #   #       #         #   #       # ");

     printf("                    #      #  #         #  #     #  #         # ");

     printf("                    ######## #           # ####### #           # ");

     printf("           /             /       |       | |       | |       |      / ");

     printf("          /             /        |       | |       | |       |     / ");

     printf("         /             /         |_______| |_______| |       |    / ");

     printf("        /             /______    |       | |       | |-----  |    / ");

     printf("       /             /           |       | |       | |     | |   /  ");

     printf("     --------------  /            |       | |       | |     | |  /    ");

     printf("     |            | /            |       | |       |  ----- ");

     for(i = 1; i <= 78; i++)

          printf("%c", 177);

     printf(" %16c", 201);

     for(i = 1; i <= 47; i++)

          printf("%c", 205);

     printf("%c %16c%48c", 187, 186, 186);

     printf(" %16c  Completed student group 13VV2 Sergey Vtorov  %c %16c%48c", 186, 186, 186, 186);

     printf(" %16c                 PSU (C) 2014                  %c %16c%48c", 186, 186, 186, 186);

     printf(" %16c    To view the main menu, press any key...    %c %16c%48c", 186, 186, 186, 186);

     printf(" %16c", 200);

     for(i = 1; i <= 47; i++)

          printf("%c", 205);

     printf("%c ", 188);

     getch();     

     mmenu();      // Показать главное меню

}

Файл «sort.c»

#include "my.h"

unsigned char sorttag() {    // Запрос выбора критерия сортировки

     line = 4; // Количество критериев сортировки

     pos = 1;

     sortupdate(pos);   // Обновление окна

     do {

          key = getch();

          switch(key) {

              case 72: {    // Нажата стрелка вверх

                             /*

                             pos = pos - 1;

                             if(pos == 0)

                                 pos = line;

                             */

                             __asm {

                                 mov al, pos; 

                                 mov bl, line;

                                 sub al, 1;    // pos = pos - 1  

                                 cmp al, 0;   

                                 je equally;             // если al = 0, перейти по метке equally  

                                 jmp assignment;         // безусловный переход по метке assignment

                                 equally:

                                      mov al, bl;        // pos = line

                                 assignment:        // Значение из регистра al в переменную pos

                                      mov pos, al;

                             }

                             sortupdate(pos);  

                             break;

                         }

              case 80: {    // Нажата стрелка вниз

                             pos++;

                             if(pos == (line + 1))

                                 pos = 1;

                             sortupdate(pos);  

                             break;

                         }

              case 13: {    // Нажат ввод

                             key = 0;

                             break;

                         }

          }

     } while(key != 0);

     return pos;

}

void sortupdate(unsigned char pos) {  // Обновление запроса критерия сортировки

     system("cls");

     printf(" %27c", 201);   

     for(i = 1; i <= 22; i++)

          printf("%c", 205);

     if(pos == 1) {

          printf("%c %27c * product name       %c %27c", 187, 186, 186, 204);

     } else

          printf("%c %27c   product name       %c %27c", 187, 186, 186, 204);

     for(i = 1; i <= 22; i++)

          printf("%c", 205);

     if(pos == 2) {

          printf("%c %27c * product code       %c %27c", 185, 186, 186, 204);

     } else

          printf("%c %27c   product code       %c %27c", 185, 186, 186, 204);

     for(i = 1; i <= 22; i++)

          printf("%c", 205);

     if(pos == 3) {

          printf("%c %27c * number of products %c %27c", 185, 186, 186, 204);

     } else

          printf("%c %27c   number of products %c %27c", 185, 186, 186, 204); 

     for(i = 1; i <= 22; i++)

          printf("%c", 205);

     if(pos == 4) {

          printf("%c %27c * product cost       %c %27c", 185, 186, 186, 200);

     } else

          printf("%c %27c   product cost       %c %27c", 185, 186, 186, 200);

     for(i = 1; i <= 22; i++)

          printf("%c", 205);

     printf("%c ", 188);   

}

Приложение B Снимки экрана Заставка

 




Главное меню


Меню сортировки

 



Таблица товаров

 



Приложение С Результат работы программы Файл data.txt:

13

Paper*00111*500*199

Pan*abccc*950*25

Battery "Panasonic"*192md*300*49

Notebook*01111*1200*2

Pan (Gel)*abddd*400*50

Chair*888abc*75*900

Notebook (18 pages)*01113*500*3

Clock "Fossil"*ch2564*33*4360

Toaster "Philips"*ff45hj*125*2190

Notebook (96 pages)*01112*87*45

Dishes*dufhhf*42*420

Clock "Casio"*110ts*13*7490

Whatman Paper*002222*140*20

Информация о файле
Название файла Разработка программы сложной структуры методом нисходящего программирования от пользователя numed
Дата добавления 10.5.2020, 21:03
Дата обновления 10.5.2020, 21:03
Тип файла Тип файла (zip - application/zip)
Скриншот Не доступно
Статистика
Размер файла 357.24 килобайт (Примерное время скачивания)
Просмотров 617
Скачиваний 78
Оценить файл