} 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,"\n\r Список книг, выбранных по маске \n\r")
// Перебор всех элементов
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р\n\r",cdt[n].number,cdt[n].fio,
cdt[n].name,cdt[n].num,cdt[n].price)
}
// Закрывается файл
fclose(f)
printf("\n\n Нажмите любую клавишу для продолжения")
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)
}