Пояснительная записка к курсовой работе по дисциплине “Основы алгоритмизации и программирования”
Выполнил : студент гр. 96-ВВ3 Митиков Р.О.
Пензенский государственный университет, Кафедра “Вычислительная Техника”
Пенза 1998
С момента появления первых образцов персональных компьютеров прошло не так уж и много времени,но сейчас без них уже немыслимо огромное количество областей человеческой деятельности - экономика , управление , наука , инженерное дело , издательское дело , образование , культура и т.д.
Интерес к персональным компьютерам постоянно растет,а круг их пользователей непрерывно расширяется.В число пользователей ПЭВМ вовлекаются как новички в компьютерном деле,так и специалисты по другим классам ЭВМ.
Язык С++ - универсальный язык общего назначения, область приложений которого - программирование систем в самом широком смысле. Кроме этого, С++ успешно используется как во многих приложениях, так и в мощных операционных системах. Реализация С++ осуществлена для машин в диапазоне от самых простых персональных компьютеров до самых мощных суперкомпьютеров и для всех операционных систем.
Задача курсовой работы состоит в разработке на языке программирования С++ программы обработки данных в библиотеке , которая должна осуществлять следующие функции:
1) Ввод данных о книгах , имеющихся в библиотеке:название книги , автор , количество экземпляров , порядковый номер , стоимость книги
2) Вывод информации на экран (в файл) по запросу о книгах , имеющихся в библиотеке: читальном зале , абонементе , хранилище по названию , автору, тематике.
3) Сбор статистики о книгах одного автора с разными названиями.
4) Построение графической диаграммы для пункта по выбору.
Работа программы должна быть организована с использованием меню.
Программу разработать на языке С++ v.3.1.
Анализируя постановку задачи становится ясно , что для её решения необходимо применить метод многофункционального программирования - этот метод основан на разбиении программы на отдельные функциональные модули , которые вызываются из основной программы в процессе её работы.
В основе разработки такой программы лежит низходящее программирование - т.е. сначала разрабатывается основная программа - в данном случае программа ввода текста на экран , обработки функциональных клавиш и меню , с помощью выбора пунктов которого будет в дальнейшем организовываться её работа. При выборе того или иного пункта меню или нажатии функциональной клавиши будет вызываться одна или несколько подпрограмм , но на начальном этапе разработки программы методом нисходящего программирования вместо этих подпрограмм ставяться "заглушки" - пустые подпрограммы , которые в процессе разработки будут заменяться программами , выполняющими определённую функцию.
Входными данными в программе являются:
Файл базы данных , который записан на диске в файле librarym.dat.
Данные , которые в процессе работы программы можно добавить , удалить или отредактировать.
Выходными данными в программе являются:
Данные , сортированные по названию или автору
Результат поиска по заданной маске
График
Файл базы данных , который записывается на диск в файл librarym.dat при завершении работы программы.
Данные об книге хранятся в массиве структур типа books:
Структура books:
Поле | Тип | Название |
name | строка 30 символов типа char | Название |
fio | строка 30 символов типа char | Автор |
num | int | Количество |
price | float | Стоимость |
number | long | Порядковый номер |
loc | int | Расположение |
ss | int | Тематика |
nn | int | Номер по названию |
nf | int | Номер по автору |
Глобальные переменные программы:
Поле | Тип | Название |
cdt | массив переменных типа books на 501 элемент | Массив данных о странах |
cnum | Int | Количество книг |
sort | Char | тип сортировки |
ftm | Char | Расположение |
6 Спецификация на функциональные модули
6.1 Функция cmp
Строка вызова: | if (cmp(cdt[n].name,cdt[500].name)&&cmp(cdt[n].fio,cdt[500].fio)&& (cdt[n].price>=cdt[500].price)) |
Назначение: | Осуществляет сравнение строки с маской |
Функции: | Просматривает последовательно заданную строку , и если в ней найдена маска , то возвращается 1 , если нет - 0. |
Логические переменные: |
*a (char) - указатель на строку *b (char) - указатель на маску для поиска |
Внутренние переменные: |
k (int) - результат сравнения n (int) - счётчик |
Вызывает функции: | нет |
Вызывается из: | index , find |
6.2 Функция output
Строка вызова: | output(sv,sk) |
Назначение: | Осуществляет вывод на экран списка книг |
Функции: | Очистка экрана , вывод 10 элементов , если элемент выбран , выделение цветом , вывод данных о книге на экран. |
Логические переменные: |
sv,sk (int) - координаты первого элемента на экране |
Внутренние переменные: |
n (int) - счётчик m (int) - временная переменная nd (int) - порядковый номер данной книги |
Вызывает функции: | нет |
Вызывается из: | scroll |
6.3 Функция menu
Строка вызова: |
st=menu(30,5,"Добавить в список " "Удалить из списка " "Редактировать " "По Автору " "По Названию " "Выход в главное меню" "x0") st=menu(30,5," Список книг " " Поиск по маске " " Количество книг " " Выход из программы " "x0") st=menu(40,6," Расположение: " " Читальный зал " " Абонемент " " Хранилище " "x0") |
Назначение: | Осуществляет обработку меню |
Функции: | Вывод меню на экран , опрос клавиатуры , при нажатии клавиш управления курсором (вверх , вниз) перемещение цветового курсора по пунктам меню , выбор определённого пункта меню при нажатии клавиши с номером пункта меню , при нажатии клавиши Enter возвращается номер выбранного пункта меню , при нажатии клавиши Esc возвращается -1. |
Логические переменные: |
*capt (char) - указатель на текст меню x,y - координаты вывода меню на экран |
Внутренние переменные: |
n,m (int) - Счетчики num (int) - Количество пунктов k (int) - Выбранный пункт *pt (char) - Временный указатель на символ c (char) - Считанный с клавиатуры символ |
Вызывает функции: | нет |
Вызывается из: | scroll , main |
6.4 Функция sinput
Строка вызова: |
SInput(cdt[ed].name,30,35,6) SInput(cdt[ed].fio,30,35,8) SInput(name,40,20,23) |
Назначение: | Осуществляет ввод строки. |
Функции: | Вывод пустой строки , установка координат , вывод строки запроса, считывание строки посимвольно с клавиатуры , выход , если нажата клавиша Enter или Esc , если нажата Esc то строка не записывается. |
Логические переменные: |
*s (char) - указатель на строку lng (int) - максимальная длина x,y - координаты ввода |
Внутренние переменные: |
rs[100] (char) - Временная строка n (int) - Счетчик c (char) - Введённый с клавиатуры символ |
Вызывает функции: | нет |
Вызывается из: | edit , find |
6.5 Функция dinput
Строка вызова: |
cdt[ed].price=DInput(35,10) cdt[ed].number=DInput(35,12) cdt[ed].num=DInput(35,14) |
Назначение: | Осуществляет ввод числа. |
Функции: | Вывод пустой строки , установка координат , вывод строки запроса, считывание строки посимвольно с клавиатуры , получение введённого числа , выход , если нажата клавиша Enter или Esc , если нажата Esc то число не записывается. |
Логические переменные: |
*s (char) - указатель на строку lng (int) - максимальная длина x,y - координаты ввода |
Внутренние переменные: |
s[100] (char) - Временная строка * сtpe (char) - указатель на сторку rs (double) - Результат n (int) - Счетчик c (char) - Введённый с клавиатуры символ |
Вызывает функции: | нет |
Вызывается из: | edit |
6.6 Функция graph
Строка вызова: | graph() |
Назначение: | Осуществляет построения столбчатой диаграммы по распределению книг . |
Функции: | Определение масштаба , построение осей координат , вывод диаграммы , ожидание нажатия пользователем клавиши. |
Логические переменные: |
нет |
Внутренние переменные: |
drv,mode (int) - для инициализации графики c (int) - Цвет k1,k2,k3 (int) - количество книг n (int) - Счетчик m (int) - Масштаб |
Вызывает функции: | нет |
Вызывается из: | main |
6.7 Функция index
Строка вызова: | index() |
Назначение: | Осуществляет индексирование массива - назначение номеров элементов по алфавиту для каждого поля записи. |
Функции: | Cтирание старых индексов , перебор всех возможных мест хранения , индексация по автору , поиск наименьшего , индексация по названию , поиск наименьшего. |
Логические переменные: |
нет |
Внутренние переменные: |
n,m (int) - счётчики tm (int) - перебор тем mxc (char[100]) - значение наименьшей строки nm (int) - номер очередного элемента |
Вызывает функции: | cmp |
Вызывается из: | scroll |
6.8 Функция edit
Строка вызова: |
edit(cnum-1) edit(n) edit(500) |
Назначение: | Осуществляет редактирование элемента массива. |
Функции: | Ввод данных , вывод одного из полей структуры , опрос клавиатуры , выбор действия - редактирование поля или выход (клавиша Esc). |
Логические переменные: |
ed (int) - номер элемента массива |
Внутренние переменные: |
n (int) - счётчик en (int) - редактируемое поле c (char) - Введённый с клавиатуры символ |
Вызывает функции: | sinput , dinput |
Вызывается из: | scroll |
6.9 Функция find
Строка вызова: | find() |
Назначение: | Осуществляет поиск элемента в заданной строке по заданной маске. |
Функции: | Поиск элемента , Возврат результатов в файл или на экран. |
Логические переменные: |
нет |
Внутренние переменные: |
n (int) - счётчик *F(file - файл ввода name[50] (char) - Имя файла |
Вызывает функции: | cmp , sinput |
Вызывается из: | main |
6.10 Функция scroll
Строка вызова: | scroll () |
Назначение: | Осуществляет обработку списка. |
Функции: | Вывод списка на экран , ввод символа с клавиатуры, обработка символа , в воодветствии с нажатой клавишей вызов меню , выбор пункта меню , выполнение действия , выход. |
Логические переменные: |
нет |
Внутренние переменные: |
st (int) - номер выбранного пункта меню n (int) - счётчик c (char) - Введённый с клавиатуры символ sv , sk (int) - первый элемент на экране и положение курсора |
Вызывает функции: | output , menu , edit , index. |
Вызывается из: | main |
6.11 Функция load
Строка вызова: | load() |
Назначение: | Осуществляет загрузку базы данных из файла. |
Функции: | Открытие файла с именем librarym.dat , чтение количества строк в массиве , чтение данных в массив , закрытие файла. |
Логические переменные: |
нет |
Внутренние переменные: |
*f (file) - указатель на файл |
Вызывает функции: | нет |
Вызывается из: | main |
6.12 Функция save
Строка вызова: | save() |
Назначение: | Осуществляет запись базы данных в файл. |
Функции: | Открытие файла librarym.dat , запись количества элементов , запись данных в файл , закрытие файла. |
Логические переменные: |
нет |
Внутренние переменные: |
*f (file) - указатель на файл |
Вызывает функции: | нет |
Вызывается из: | main |
6.13 Основная программа - main
Назначение: | Осуществляет установку начальных значений , чтение базы данных из файла , обработку , запись базы данных в файл. |
Функции: | Установка начальных значений переменных , вызов функции чтения данных из файла , вызов функции обработки , обработку меню, поиск по маске , построение диаграммы , вызов функции записи в файл ,установка параметров , выход из программы. |
Вызывает функции: | load , save , scroll , menu , find , graph. |
Для запуска данной программы необходимо наличие персонального компьютера IBM PC/XT c операционной системой MS-DOS.
Необходимый объем оперативной памяти -640 Кбайт.
Дла запуска программы необходимо сделать текущем каталог с программой kurs.exe и вызвать её на выполнение.
Программа работает в текстовом режиме 80х25 символов , построение диаграммы осуществляется в графическом режиме 640х480 точек 16 цветов.
Файл базы данных программы librarym.dat будет записываться и считываться из текущего каталога текущего диска.
Управление программой осуществляется с клавиатуры.
После своей загрузки программа осуществляет оформление экрана , вывод на экран списка книг , содержащийся в файле базы данных , по которым можно передвигать цветовой курсор.
При нажатии клавиши Enter на одном из элементов списка , то на экран будет вызванно меню:
1) Список книг |
2) Поиск по маске |
3) Количество книг |
4) Выход из программы |
При выборе первого пункта меню моявится следующее подменю:
1) Ðàñïîëîæåíèå: |
2) ×èòàëüíûé çàë |
3) Àáîíåìåíò |
4) Õðàíèëèùå |
При нажатии пользователем клавиши Enter на выведенном списке книг появляется меню:
1) Äîáàâèòü â ñïèñîê |
2) Óäàëèòü èç ñïèñêà |
3) Ðåäàêòèðîâàòü |
4) Ïî Àâòîðó |
5) Ïî Íàçâàíèþ |
6) Âûõîä â ãëàâíîå ìåíþ |
При нажатии на клавиши управления курсором (вверх , вниз) можно управлять курсором , если нажать клавишу Enter или клавишу с номером пункта меню , то произойдёт то или иное действие в соответствии с выбранным пунктом.
Отсортированная последовательность выводится на экран в виде списка книг. При выборе пункта "Поиск по маске" программа запрашивает данные для поиска книги: Название , Автор , Стоимость , Порядковый номер , Количество , Тематика (Не влияет).
После поиска , если такая книга имеется в списке , данные о найденной книги выводятся на экран.
При выборе пункта "Выход из программы" программа завершает свою работу.
Для полной проверки работоспособности программы необходимо её протестировать.
План тестирования программы учёта и выборки информации о странах состоит в следующем:
1) Загрузка программы
2) Ввод данных о книгах
3) Удаление книги из списка
4) Редактирование данных о книге
5) Сортировка
6) Поиск по маске
7) Построение диаграммы
8) Выход из программы
Далее в пункте "Результаты работы программы" приводится распечатка тестирования программы по пунктам плана тестирования и результатов тестирования.
10 Результаты работы программы
2) Ввод данных о книгах
76 Автор2 Книга9 22 11.00р
11 Автор2 Книга8 28 21.00р
22 Автор65 Книга33 18 32.00р
55 Автор1 Книга3 12 22.00р
2 Автор2 Книга2 10 55.00р
1 Автор1 Книга 1 10 34.00р
3) Удаление книги из списка
76 Автор2 Книга9 22 11.00р
11 Автор2 Книга8 28 21.00р
22 Автор65 Книга33 18 32.00р
55 Автор1 Книга3 12 22.00р
2 Автор2 Книга2 10 55.00р
4) Редактирование данных о книге
Название: Книга3
Автор: Автор1
Стоимость: 20.00
Порядковый номер: 55
Количество: 20
Тематика: Научная
5) Сортировка
По автору:
22 Автор65 Книга33 18 32.00р
76 Автор2 Книга9 22 11.00р
2 Автор2 Книга2 10 55.00р
11 Автор2 Книга8 28 21.00р
55 Автор1 Книга3 20 20.00р
По названию:
76 Автор2 Книга9 22 11.00р
11 Автор2 Книга8 28 21.00р
22 Автор65 Книга33 18 32.00р
55 Автор1 Книга3 20 20.00р
2 Автор2 Книга2 10 55.00р
7) Построение диаграммы
В данной курсовой работе решена задача разработки программы обработки данных в библиотеке.
По заданию к данной курсовой работе был разработан алгоритм , по которому на алгоритмическом языке С++ была разработанна программа , анализ результатов которой показал , что поставленная задача успешно решается.
1.Бьярн Страуструп. Язык программирования С++.в двух частях. Пер. с англ. Киев:"ДиаСофт",1993.-296 с.,ил.
2.Корриган Джон Компьютерная графика: Секреты и решения: Пер с англ. -М.:Энтроп, 1995. - 352 с., ил.
ПРИЛОЖЕНИЕ 1
Распечатка программы
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <graphics.h>
#include <conio.h>
// Структура - данные о одной книге
struct books {
char name[30]
// Название
char fio[30]
// Автор
int num
// Количество
float price
// Стоимость
long number
// Порядковый номер
// Расположение: 0-читальный зал, 1-абонемент, 2-хранилище
int loc
int tem
// Тематика
int nn,nf
// Номер по названию, автору
}
// Массив - 500 книг и маска для поиска
books cdt[501]
// Массив данных о книгах
int cnum
// Количество книг
// Сортировать по: 1-Названию, 2-автору
char sort
// Расположение
char ftm
const char location[3][15]={" Читальный залx0",
" Абонементx0",
" Хранилищеx0"}
const char tema[5][15]={ "Художественнаяx0",
" Техническаяx0",
" Научнаяx0",
" Справочникx0",
" _Не влияет_ x0"}
// ПРОТОТИПЫ ФУНКЦИЙ
// Сравнение строки с маской
int cmp(char * a,char * b)
// Вывод списка на экран
void output(int sv,int sk)
// Обработка меню
int menu(int x,int y,char * capt)
// Ввод строки
void SInput(char * s,int lng,int x,int y)
// Ввод числа
double DInput(int x,int y)
// Индексирование массива
void index()
// Редактирование элемента
void edit(int ed)
// Вывод данных по маске
void find()
// Вывод графика
void graph()
// Обработка списка
void scroll()
// Чтение массива
void load()
// Запись массива
void save()
// ТЕЛА ФУНКЦИЙ
// Сравнение строки с маской
// a- строка, b- маска
int cmp(char * a,char * b) {
int k
int n
k=1
for (n=0
n<strlen(b)
n++)
if (a[n]!=b[n]) k=0
return k
}
// Вывод списка на экран
void output(int sv,int sk) {
int n
int m
int nd
m=sv
// Очистка экрана
textcolor(15)
textbackground(1)
clrscr()
// Вывод двадцати элементов
for (n=1
n<20
n++) {
// Если элемент выбран, изменение цветов
if (n==sk) {
textbackground(14)
} else {
textbackground(1)
}
if (m<(cnum+1)) {
nd=0
// Поиск элемента с данным индексом
switch (sort) {
case(1):
while (((cdt[nd].nn!=m)||(cdt[nd].loc!=ftm))&&(nd<cnum+1)) nd++
break
case(2):
while (((cdt[nd].nf!=m)||(cdt[nd].loc!=ftm))&&(nd<cnum+1)) nd++
break
}
switch (sort) {
case(1):
if ((cdt[nd].nn!=m)||(cdt[nd].loc!=ftm)) nd=-1
break
case(2):
if ((cdt[nd].nf!=m)||(cdt[nd].loc!=ftm)) nd=-1
break
}
m++
// Вывод данных о стране на экран
gotoxy(1,m-sv)
if (nd!=-1)
cprintf("%4ld %30s %30s %4d %6.2fр",cdt[nd].number,cdt[nd].fio,
cdt[nd].name,cdt[nd].num,cdt[nd].price)
}
}
textbackground(1)
}
// Обработка меню
int menu(int x,int y,char * capt) {
int n,m
// Счетчики
int num
// Количество пунктов
int k
// Выбранный пункт
char * pt
// Временный указатель на символ
char c
// Считанный с клавиатуры символ
// Вычисляем количество пунктов
num=strlen(capt)/20
// Курсор на нулевой элемент
k=0
// Бесконечный цикл обработки
for (
) {
// Вывод меню
pt=capt
for (n=0
n<num
n++) {
gotoxy(x,y+n)
// Закраска пункта, на который указывает курсор
if (n==k) {
// Закраска
textbackground(12)
textcolor(14)
} else {
// Нормальный
textbackground(3)
textcolor(1)
}
cprintf("%d) ",n+1)
for (m=0
m<20
m++) cprintf("%c",*(pt++))
}
textbackground(3)
textcolor(1)
// Опрос клавиатуры
c=getch()
if (!c) c=getch()
// Проверка, не нажата ли клавиша с цифрой
if (((c-'1')>=0)&&((c-'1')<num)) {
// Установка указателя в зависимости от нажатой цифры
k=c-'1'
// Запись в буфер клавиатуры символа ENTER
ungetch(13)
} else {
// Анализ
switch(c) {
// Вверх
case (72):
if (k>0) k--
else k=num-1
break
// Вниз
case (80):
if (k<(num-1)) k++
else k=0
break
// Выход по ESC - возвращается -1
case (27):
return -1
// Выход по ENTER - возвращается номер пункта
case (13): return k
}
}
}
}
// Ввод строки
// s - указатель на строку
// lng - Максимальная длинна
// x,y - координаты
void SInput(char * s,int lng,int x,int y) {
lng--
char rs[100]
// Временная строка
strcpy(rs,s)
// Копирование резерва строки
int n
// Счетчик
char c
// Символ
_setcursortype(_NORMALCURSOR)
// Вывод пустой строки
textbackground(2)
textcolor(15)
gotoxy(x,y)
for (n=0
n<lng
n++) cprintf(" ")
n=strlen(s)
// Положение курсора
do {
// Вывод строки
gotoxy(x,y)
cprintf("%s ",s)
gotoxy(x+n,y)
c=getch()
// Считывание символа с клавиатуры
if ((c!=13)&&(c!=27)&&(c!=8)) {
// Нажата символьная клавиша
if (n<(lng-1)) {
// Добавление символа
s[n+1]=0
s[n]=c
n++
}
} else {
if (c==8) {
// Нажата клавиша BackSpace
if (n>0) {
n--
s[n]=0
}
}
}
// Выход, если ESC или ENTER
} while ((c!=27)&&(c!=13))
if(c==27) strcpy(s,rs)
// Восстановление строки
// Стирание строки
textbackground(0)
textcolor(7)
gotoxy(x,y)
for (n=0
n<lng+1
n++) cprintf(" ")
_setcursortype(_NOCURSOR)
}
// Ввод числа
// x,y - координаты
double DInput(int x,int y) {
char s[100]
// Временная строка
char *stpe
double rz
s[0]=0
int n
// Счетчик
char c
// Символ
// Вывод пустой строки
_setcursortype(_NORMALCURSOR)
textbackground(2)
textcolor(15)
gotoxy(x,y)
for (n=0
n<15
n++) cprintf(" ")
n=strlen(s)
// Положение курсора
do {
// Вывод строки
gotoxy(x,y)
cprintf("%s ",s)
gotoxy(x+n,y)
c=getch()
// Считывание символа с клавиатуры
if ((c!=13)&&(c!=27)&&(c!=8)) {
// Нажата символьная клавиша
if (n<14) {
// Добавление цифры или точки
if ((c>='0')&&(c<='9')||(c=='.')) {
s[n+1]=0
s[n]=c
n++
}
}
} else {
if (c==8) {
// Нажата клавиша BackSpace
if (n>0) {
n--
s[n]=0
}
}
}
// Выход, если ESC или ENTER
} while ((c!=27)&&(c!=13))
if(c==27) return 0
// Стирание строки
textbackground(0)
textcolor(7)
gotoxy(x,y)
for (n=0
n<15
n++) cprintf(" ")
rz=strtod(s,&stpe)
_setcursortype(_NOCURSOR)
return rz
}
// Индексирование массива - Назначение номеров элементов
void index() {
int tm
// Перебор тем
int n,m
// Счетчики
char mxc[100]
// Значение наименьшей строки
int nm
// Номер очередного элемента
// Стирание старых индексов
for (n=0
n<cnum
n++) {
cdt[n].nn=0
cdt[n].nf=0
}
// Перебор всех возможных мест хранения
for (tm=0
tm<3
tm++) {
// Индексация по автору
for (m=0
m<cnum
m++) {
// Поиск наименьшего
strcpy(mxc,"x0")
nm=-1
for (n=0
n<cnum
n++)
if ((cdt[n].nf==0)&&(cdt[n].loc==tm))
if (strcmp(cdt[n].fio,mxc)>0) {
strcpy(mxc,cdt[n].fio)
nm=n
}
if (nm!=-1) cdt[nm].nf=m+1
}
// Индексация по названиям
for (m=0
m<cnum
m++) {
// Поиск наименьшего
strcpy(mxc,"x0")
nm=-1
for (n=0
n<cnum
n++)
if ((cdt[n].nn==0)&&(cdt[n].loc==tm))
if (strcmp(cdt[n].name,mxc)>0) {
strcpy(mxc,cdt[n].name)
nm=n
}
if (nm!=-1) cdt[nm].nn=m+1
}
}
}
// Редактирование элемента массива
void edit(int ed) {
clrscr()
// Обработка
int n
// Счетчик
int en=0
// Редактируемое поле
char c
// Символ с клавиатуры
for(
) {
// Вывод данных
for (n=0
n<6
n++) {
// Изменение цвета если элемент выбран
if (n==en) {
textbackground(12)
textcolor(15)
} else {
textbackground(1)
textcolor(7)
}
gotoxy(15,6+2*n)
// Вывод одного из полей структуры
switch(n) {
case 0:
cprintf(" Название: %45s",cdt[ed].name)
break
case 1:
cprintf(" Автор: %45s",cdt[ed].fio)
break
case 2:
cprintf(" Стоимость: %45.2f",cdt[ed].price)
break
case 3:
cprintf(" Порядковый номер: %45d",cdt[ed].number)
break
case 4:
cprintf(" Количество: %45d",cdt[ed].num)
break
case 5:
cprintf(" Тематика: %45s",tema[cdt[ed].tem])
}
}
// Опрос клавиатуры
c=getch()
if (!c) c=getch()
switch(c){
// Вверх
case (72):
en--
if (en<0) en=5
break
// Вниз
case (80):
en++
if (en>5) en=0
break
// ENTER - Редактирование поля или выход
case (13):
// Выбор действия
switch(en) {
case 0:
SInput(cdt[ed].name,30,35,6)
break
case 1:
SInput(cdt[ed].fio,30,35,8)
break
case 2:
cdt[ed].price=DInput(35,10)
break
case 3:
cdt[ed].number=DInput(35,12)
break
case 4:
cdt[ed].num=DInput(35,14)
break
case 5:
// Изменение тематики
cdt[ed].tem=(cdt[ed].tem+1)%4
break
}
break
case(27):
return
}
}
}
// Вывод по маске
void find() {
int n
// Счетчик
FILE * f
// Файл вывода
char name[50]
// Имя файла
strcpy(name,"CON")
// Изначально - CON, т.е. экран
// Ввод имени файла вывода
textbackground(0)
clrscr()
gotoxy(1,23)
cprintf(" Введитеимя файла: ")
SInput(name,40,20,23)
// Открывается файл на запись
f=fopen(name,"wb")
if (f==NULL) return
fprintf(f,"nr Список книг, выбранных по маске nr")
// Перебор всех элементов
for (n=0
n<cnum
n++)
// Если удовлетворяет условию
if (cmp(cdt[n].name,cdt[500].name)&&
cmp(cdt[n].fio,cdt[500].fio)&&
(cdt[n].price>=cdt[500].price)) {
// Вывод в файл
fprintf(f,"%4ld %30s %30s %4d %6.2fрnr",cdt[n].number,cdt[n].fio,
cdt[n].name,cdt[n].num,cdt[n].price)
}
// Закрывается файл
fclose(f)
printf("nn Нажмите любую клавишу для продолжения")
getch()
}
// Вывод графика
void graph() {
// Ингициализация графики
int c
// Цвет
int drv,mode
// Для инициализации графики
int k1,k2,k3
// Количество книг
int n
// Счетчик
int m
// Масштаб
drv=DETECT
initgraph(&drv,&mode,"")
// Подсчет количества книг
k1=k2=k3=0
for (n=0
n<cnum
n++) {
switch(cdt[n].loc) {
case (0):
k1++
break
case (1):
k2++
break
case (2):
k3++
break
}
}
// Определение максимального
if (k1>k2) m=k1
else m=k2
if (m<k3) m=k3
// Определение масштаба
m=400/m
// Вывод столбчатой диаграммы
line(0,470,640,470)
line(10,0,10,480)
outtextxy(100,20," Распределение книг ")
// Рассчет цвета столбца - 12 - максимальное значение
c=12
if (k2>k1) c--
if (k3>k1) c--
setfillstyle(9,c)
bar3d(20,470-m*k1,120,470,10,1)
// Рассчет цвета столбца - 12 - максимальное значение
c=12
if (k1>k2) c--
if (k3>k2) c--
setfillstyle(9,c)
bar3d(140,470-m*k2,240,470,10,1)
// Рассчет цвета столбца - 12 - максимальное значение
c=12
if (k1>k3) c--
if (k2>k3) c--
setfillstyle(9,c)
bar3d(260,470-m*k3,360,470,10,1)
// Вывод поясняющих надписей
setcolor(14)
outtextxy(30,450-m*k1,"Читальный зал")
outtextxy(150,450-m*k2,"Абонемент")
outtextxy(270,450-m*k3,"Хранилище")
// Ожидание нажатия клавиши
getch()
closegraph()
_setcursortype(_NOCURSOR)
}
// Обработка списка
void scroll() {
char c
// Считанный с клавиатуры символ
static int sv=1,sk=1
// Первый элемент на экране и положение курсора
int st
// Выбранный пункт меню
int n
// Счетчик
// Цикл обработки
do {
// Вывод списка на экран
output(sv,sk)
// Ввод символа
c=getch()
if (!c) c=getch()
// Обработка символа
switch (c) {
// Вверх
case (72):
if (sk>1) sk--
else if (sv>1) sv--
break
// Вниз
case (80):
if (sk<7) {
if (sk<(cnum-sv+1)) sk++
} else if (sv<(cnum-7)) sv++
break
// Меню
case (13):
st=menu(30,5,"Добавить в список "
"Удалить из списка "
"Редактировать "
"По Автору "
"По Названию "
"Выход в главное меню"
"x0")
switch(st) {
case (0):
if (cnum<299) {
cdt[cnum].name[0]=0
cdt[cnum].fio[0]=0
cdt[cnum].price=0
cdt[cnum].number=0
cdt[cnum].num=0
cdt[cnum].tem=0
cdt[cnum].loc=ftm
cnum++
edit(cnum-1)
}
index()
break
case (1):
// Удаление элемента
if (cnum>1) {
n=0
switch (sort) {
case (1):
while (((cdt[n].nn!=sk+sv-1)||(cdt[n].loc!=ftm))&&(n<cnum+1)) n++
break
case (2):
while (((cdt[n].nf!=sk+sv-1)||(cdt[n].loc!=ftm))&&(n<cnum+1)) n++
break
}
if (n!=(cnum+1)) {
strcpy(cdt[n].name,cdt[cnum-1].name)
strcpy(cdt[n].fio,cdt[cnum-1].fio)
cdt[n].price=cdt[cnum-1].price
cdt[n].num=cdt[cnum-1].num
cdt[n].number=cdt[cnum-1].number
cdt[n].loc=cdt[cnum-1].loc
cdt[n].tem=cdt[cnum-1].tem
cnum--
index()
}
}
break
// Редактирование элемента
case (2):
n=0
switch (sort) {
case (1):
while (((cdt[n].nn!=sk+sv-1)||(cdt[n].loc!=ftm))&&(n<cnum+1)) n++
break
case (2):
while (((cdt[n].nf!=sk+sv-1)||(cdt[n].loc!=ftm))&&(n<cnum+1)) n++
break
}
edit(n)
index()
break
case (3):
case (4):
sort=5-st
break
case (5):
// Выход в предыдущее меню
return
}
break
}
} while(c!=27)
}
// Чтение массива
void load() {
// Открытие файла на чтение
FILE * f
f=fopen("librarym.dat","rb")
if (f==NULL) return
// Чтение количества книг
fread(&cnum,1,2,f)
// Чтение массива
fread(cdt,cnum,sizeof(books),f)
// Закрытие файла
fclose(f)
}
// Запись файла
void save() {
// Открытие файла на запись
FILE * f
f=fopen("librarym.dat","wb")
if (f==NULL) {
printf(" !!! ОШИБКА ПРИ ЗАПИСИ БАЗЫ ДАННЫХ !!! n")
return
}
// Запись количества элементов в массив
fwrite(&cnum,1,2,f)
// Запись массива
fwrite(cdt,cnum,sizeof(books),f)
// Закрытие файла
fclose(f)
}
// Основная программа
void main() {
int st
// Установка начальных значений
_setcursortype(_NOCURSOR)
cnum=0
sort=1
ftm=0
// Чтение массива
load()
index()
// Обработка
do {
// Основное меню
textcolor(15)
textbackground(0)
clrscr()
st=menu(30,5," Список книг "
" Поиск по маске "
" Количество книг "
" Выход из программы "
"x0")
switch(st) {
case (0):
// Подменю для вывода списка
st=menu(40,6," Расположение: "
" Читальный зал "
" Абонемент "
" Хранилище "
"x0")
if (st!=0) {
ftm=st-1
scroll()
st=0
}
break
case (1):
// Поиск
cdt[500].name[0]=0
cdt[500].fio[0]=0
cdt[500].price=0
cdt[500].number=0
cdt[500].num=0
cdt[500].tem=4
edit(500)
find()
break
case (2):
// Вывод графика
graph()
break
}
} while (st!=3)
// Выход из программы
textcolor(7)
textbackground(0)
clrscr()
// Запись массива
save()
_setcursortype(_NORMALCURSOR)
}