Список используемых источников 1. К. Поляков. «Программирование на языке Си (Глава IV.
Динамические структуры данных)».
2. А. А. Вылиток. «Язык Си. Реализация списков с помощью цепочек
динамических объектов».
3. MSDN.
4. Свободная энциклопедия Википедия.
Приложение А
Листинг программы
Файл «my.h»
#define _CRT_SECURE_NO_WARNINGS // Макрос для отключения предупреждений об устаревших функциях
#define _CRT_NONSTDC_NO_DEPRECATE // Макрос для отключения предупреждений о "POSIX" функциях
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <windows.h>
#include <string.h>
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\n", &j); // Получение количества строк в файле
// Заполнить первую запись
p = (struct OPT*)(malloc(sizeof(struct OPT)));
fscanf(fp, "%[^*]*%[^*]*%d*%d\n", 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\n", 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\n", datasize()); // Запись количества строк в первую строку файла
p = first;
while(p != NULL){
// Запись строк с использованием разделителей (* для колонок, \n для строк)
fprintf(fp, "%s*%s*%d*%d\n", 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("\n%4c", 201); // Вывод верхней границы таблицы
for(i = 1; i <= 69; i++)
printf("%c", 205);
printf("%c\n%4c%8c%35c%9c%9c%9c", 187, 186, 186, 186, 186, 186, 186);
printf("\n%4c #%4c", 186, 186); // Номер строки
printf(" Title%16c", 186); // Название товара
printf(" Code%3c", 186); // Код товара
printf(" Number%2c", 186); // Количество товара
printf(" Cost%3c", 186); // Цена товара
printf("\n%4c%8c%35c%9c%9c%9c", 186, 186, 186, 186, 186, 186);
j = 1;
p = first;
while (p != NULL) { // Вывод строки таблицы
printf("\n%4c", 204);
for(i = 1; i <= 69; i++)
printf("%c", 205);
printf("%c\n%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("\n%4c", 200); // Вывод нижней границы таблицы
for(i = 1; i <= 69; i++)
printf("%c", 205);
printf("%c\n\n", 188);
}
void inputdata() { // Ввод записей
do { // Ввод записей по запросу
system("cls"); // Очистка экрана после каждой введенной записи
viewdata(); // Вывод уже введенных записей
p = (struct OPT*)(malloc(sizeof(struct OPT)));
b = p;
do { // Проверка на повторение поля "Название товара"
printf("\tTitle product: ");
gets(copytitle);
} while(stest(copytitle, 1) == 0);
p = b;
strcpy(p->title, copytitle);
do { // Проверка на повторение поля "Код товара"
printf("\tCode product: ");
gets(copycode);
} while(stest(copycode, 2) == 0);
p = b;
strcpy(p->code, copycode);
do { // Проверка ввода поля "Количество товаров"
printf("\tNumber product: ");
scanf("%ld", ©store);
fflush(stdin);
} while(ntest(copystore) == 0);
p->store = copystore;
do { // Проверка ввода поля "Цена товара"
printf("\tCost 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("\n\tEnter 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("\n\tEnter the index records: ");
scanf("%ld", &index);
fflush(stdin);
} while((index <= 0) || (index > datasize()));
system("cls");
viewdata(); // Вывод имеющихся записей
do { // // Проверка на корректность ввода (перезапись всех полей)
printf("\tTitle product: ");
gets(copytitle);
} while(stest(copytitle, 1) == 0);
do {
printf("\tCode product: ");
gets(copycode);
} while(stest(copycode, 2) == 0);
do {
printf("\tNumber product: ");
scanf("%ld", ©store);
fflush(stdin);
} while(ntest(copystore) == 0);
do {
printf("\tCost 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("\tSearch: "); // Ввести критерий поиска
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("\n%4c", 201);
for(i = 1; i <= 69; i++)
printf("%c", 205);
printf("%c\n%4c%8c%35c%9c%9c%9c", 187, 186, 186, 186, 186, 186, 186);
printf("\n%4c #%4c", 186, 186); // Номер строки
printf(" Title%16c", 186); // Название товара
printf(" Code%3c", 186); // Код товара
printf(" Number%2c", 186); // Количество товара
printf(" Cost%3c", 186); // Цена товара
printf("\n%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("\n%4c", 204);
for(i = 1; i <= 69; i++)
printf("%c", 205);
printf("%c\n%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("\n%4c", 204);
for(i = 1; i <= 69; i++)
printf("%c", 205);
printf("%c\n%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("\n%4c", 200);
for(i = 1; i <= 69; i++)
printf("%c", 205);
printf("%c\n\n", 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("\n%4c", 201);
for(i = 1; i <= 69; i++)
printf("%c", 205);
printf("%c\n%4c%8c%35c%9c%9c%9c", 187, 186, 186, 186, 186, 186, 186);
printf("\n%4c #%4c", 186, 186); // Номер строки
printf(" Title%16c", 186); // Название товара
printf(" Code%3c", 186); // Код товара
printf(" Number%2c", 186); // Количество товара
printf(" Cost%3c", 186); // Цена товара
printf("\n%4c%8c%35c%9c%9c%9c", 186, 186, 186, 186, 186, 186);
for(j = 0; j < n; j++) { // Вывод строки таблицы
printf("\n%4c", 204);
for(i = 1; i <= 69; i++)
printf("%c", 205);
printf("%c\n%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("\n%4c", 200);
for(i = 1; i <= 69; i++)
printf("%c", 205);
printf("%c\n\n", 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("\n\n\n\n\n\n\n\n\n\n\n%25c", 201);
for(i = 1; i <= 26; i++)
printf("%c", 205);
if(pos == 1) {
printf("%c\n%25c >> Open File %c\n%25c", 187, 186, 186, 204);
} else
printf("%c\n%25c Open File %c\n%25c", 187, 186, 186, 204);
for(i = 1; i <= 26; i++)
printf("%c", 205);
if(pos == 2) {
printf("%c\n%25c >> Save File %c\n%25c", 185, 186, 186, 204);
} else
printf("%c\n%25c Save File %c\n%25c", 185, 186, 186, 204);
for(i = 1; i <= 26; i++)
printf("%c", 205);
if(pos == 3) {
printf("%c\n%25c >> Delete File %c\n%25c", 185, 186, 186, 204);
} else
printf("%c\n%25c Delete File %c\n%25c", 185, 186, 186, 204);
for(i = 1; i <= 26; i++)
printf("%c", 205);
if(pos == 4) {
printf("%c\n%25c >> View Data %c\n%25c", 185, 186, 186, 204);
} else
printf("%c\n%25c View Data %c\n%25c", 185, 186, 186, 204);
for(i = 1; i <= 26; i++)
printf("%c", 205);
if(pos == 5) {
printf("%c\n%25c >> Enter Data %c\n%25c", 185, 186, 186, 204);
} else
printf("%c\n%25c Enter Data %c\n%25c", 185, 186, 186, 204);
for(i = 1; i <= 26; i++)
printf("%c", 205);
if(pos == 6) {
printf("%c\n%25c >> Delete Data %c\n%25c", 185, 186, 186, 204);
} else
printf("%c\n%25c Delete Data %c\n%25c", 185, 186, 186, 204);
for(i = 1; i <= 26; i++)
printf("%c", 205);
if(pos == 7) {
printf("%c\n%25c >> Look Intro %c\n%25c", 185, 186, 186, 204);
} else
printf("%c\n%25c Look Intro %c\n%25c", 185, 186, 186, 204);
for(i = 1; i <= 26; i++)
printf("%c", 205);
if(pos == 8) {
printf("%c\n%25c >> About %c\n%25c", 185, 186, 186, 204);
} else
printf("%c\n%25c About %c\n%25c", 185, 186, 186, 204);
for(i = 1; i <= 26; i++)
printf("%c", 205);
if(pos == 9) {
printf("%c\n%25c >> Exit %c\n%25c", 185, 186, 186, 200);
} else
printf("%c\n%25c Exit %c\n%25c", 185, 186, 186, 200);
for(i = 1; i <= 26; i++)
printf("%c", 205);
printf("%c\n", 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("\n %s%s%s%s%s%s\n", itemMenu, itemAdd, itemRemove, itemEdit, itemFind, itemSort);
printf(" | Main Menu | Add | Remove | Edit | Find | Sort |\n");
printf(" %s%s%s%s%s%s\n", 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("\n\n\n\n\n\n\n\n\n\n\n\n\n%21c", 201);
for(i = 1; i <= 37; i++)
printf("%c", 205);
printf("%c", 187);
printf("\n%21c%38c", 186, 186);
printf("\n%21c%38c", 186, 186);
printf("\n%21c%33s%5c", 186, message, 186); // Сообщение
printf("\n%21c%38c", 186, 186);
printf("\n%21c%38c", 186, 186);
switch(pos) {
case 1: // Кнопка 1
{
printf("\n%21c%4c", 186, 201);
for(i = 1; i <= 12; i++)
printf("%c", 205);
printf("%c%21c\n%21c%4c%11s%2c%15s%6c\n%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("\n%21c%21c", 186, 201);
for(i = 1; i <= 12; i++)
printf("%c", 205);
printf("%c%4c\n%21c%15s%6c%11s%2c%4c\n%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("\n%21c%38c\n%21c", 186, 186, 200);
for(i = 1; i <= 37; i++)
printf("%c", 205);
printf("%c\n", 188);
}
Файл «message.c»
#include "my.h"
void report(char line1[50], char line2[50], char line3[50]) { // Вывод сообщения
system("cls");
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n%16c", 201);
for(i = 1; i <= 46; i++)
printf("%c", 205);
printf("%c\n%16c%47c\n%16c%44s%3c\n%16c%47c", 187, 186, 186, 186, line1, 186, 186, 186);
printf("\n%16c%44s%3c\n%16c%47c", 186, line2, 186, 186, 186);
printf("\n%16c%44s%3c\n%16c%47c\n%16c", 186, line3, 186, 186, 186, 200);
for(i = 1; i <= 46; i++)
printf("%c", 205);
printf("%c\n", 188);
getch();
}
void about() { // Показ информации о программе
system("cls");
printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n%16c", 201);
for(i = 1; i <= 45; i++)
printf("%c", 205);
printf("%c\n%16c%46c", 187, 186, 186);
printf("\n%16c 'Wholesale' database. %c\n%16c%46c", 186, 186, 186, 186);
printf("\n%16c Records are stored in memory or file. %c\n%16c%46c", 186, 186, 186, 186);
printf("\n%16c To return the main menu, press any key... %c", 186, 186);
printf("\n%16c%46c\n%16c", 186, 186, 200);
for(i = 1; i <= 45; i++)
printf("%c", 205);
printf("%c\n", 188);
getch();
mmenu(); // Вывод главного меню
}
void intro() { // Вывод заставки на экран
printf("\n\n **** ********* ********* **** ******* * ****\n");
printf(" * * * * * * * * * * * * * * *\n");
printf(" * * * * * * * * * * * * *\n");
printf(" * * * * * * * ******* ******* ****\n");
printf(" * * * * * * * * * * * * *\n");
printf(" * * * * * * * * * * * * *\n");
printf(" **** * * * **** ******* * * * *\n\n");
printf(" ######## # ####### #\n");
printf(" # # # # # # # #\n");
printf(" # # # # # #\n");
printf(" ######## ####### ####### #######\n");
printf(" # # # # # # #\n");
printf(" # # # # # # # #\n");
printf(" ######## # # ####### # #\n\n");
printf(" /\\ /\\ | | | | | | \\ /\n");
printf(" / \\ / \\ | | | | | | \\ /\n");
printf(" / \\ / \\ |_______| |_______| | | \\/\n");
printf(" / \\ /______\\ | | | | |----- | /\\\n");
printf(" / \\ / \\ | | | | | | | / \\\n");
printf(" -------------- / \\ | | | | | | | / \\\n");
printf(" | | / \\ | | | | -----\n\n\n");
for(i = 1; i <= 78; i++)
printf("%c", 177);
printf("\n%16c", 201);
for(i = 1; i <= 47; i++)
printf("%c", 205);
printf("%c\n%16c%48c", 187, 186, 186);
printf("\n%16c Completed student group 13VV2 Sergey Vtorov %c\n%16c%48c", 186, 186, 186, 186);
printf("\n%16c PSU (C) 2014 %c\n%16c%48c", 186, 186, 186, 186);
printf("\n%16c To view the main menu, press any key... %c\n%16c%48c", 186, 186, 186, 186);
printf("\n%16c", 200);
for(i = 1; i <= 47; i++)
printf("%c", 205);
printf("%c\n", 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("\n\n\n\n\n\n\n\n\n\n\n\n\n\n%27c", 201);
for(i = 1; i <= 22; i++)
printf("%c", 205);
if(pos == 1) {
printf("%c\n%27c * product name %c\n%27c", 187, 186, 186, 204);
} else
printf("%c\n%27c product name %c\n%27c", 187, 186, 186, 204);
for(i = 1; i <= 22; i++)
printf("%c", 205);
if(pos == 2) {
printf("%c\n%27c * product code %c\n%27c", 185, 186, 186, 204);
} else
printf("%c\n%27c product code %c\n%27c", 185, 186, 186, 204);
for(i = 1; i <= 22; i++)
printf("%c", 205);
if(pos == 3) {
printf("%c\n%27c * number of products %c\n%27c", 185, 186, 186, 204);
} else
printf("%c\n%27c number of products %c\n%27c", 185, 186, 186, 204);
for(i = 1; i <= 22; i++)
printf("%c", 205);
if(pos == 4) {
printf("%c\n%27c * product cost %c\n%27c", 185, 186, 186, 200);
} else
printf("%c\n%27c product cost %c\n%27c", 185, 186, 186, 200);
for(i = 1; i <= 22; i++)
printf("%c", 205);
printf("%c\n", 188);
}
Приложение B
Снимки экрана
Заставка
Главное меню
Меню сортировки
Таблица товаров
Приложение С
Результат работы программы
Файл data.txt:
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
|