- •Пояснительная записка
- •Содержание
- •Введение
- •Постановка задачи
- •Выбор решения Определение необходимых модулей программы.
- •Определение структуры файла базы данных.
- •Описание разработки программы
- •Отладка и тестирование
- •Описание программы Разработка приложения database.Exe
- •Разработка меню
- •Разработка функции на языке Assembler
- •Руководство пользователя
- •Заключение
- •Список используемых источников
- •Приложение а Листинг программы Файл «my.H»
- •Файл «main.C»
- •Файл «data.C»
- •Файл «mainmenu.C»
- •Файл «submenu.C»
- •Файл «dialog.C»
- •Файл «message.C»
- •Файл «sort.C»
- •Приложение b
Файл «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;
}
}
}