
Задание №5
Дано кольцо этажей в общежитии (количество мест, количество свободных мест, ФИО и группа проживающих на этаже),
если нету свободных мест, то создаётся очередь (общая на общежитие, т.е. 1-а очередь на заселение), информация должна храниться в файлах (текстовый либо бинарный).
Структура входных и выходных данных:
-
Входные:
Бинарные файлы: hostel.dat, line.dat.
struct floor
{
int bed; //количество мест
int free_bed; //количество свободных мест
int room; //количество комнат
int nomb_room[N]; //номер комнаты
char name[N][length]; //имена проживающих
int nomb; //номер этажа
};
struct ring
{
floor in; //информационное поле
ring *l, *r; //адресные поля
};
struct line
{
char fm[length]; //информационное поле
line *nx; //адресное поле
};
length=20 – размер строки, N=4 – количество мест на этаже, s – структура типа ring, lin – структура типа line.
-
Промежуточные:
x – переменная для выбора действия.
-
Выходные:
s – кольцо этажей общежития, lin – очередь на заселение.
Алгоритм по шагам функции добавления в кольцо - add_to_ring():
-
Начало.
-
Объявление переменных:
s и s1 – структуры типа ring, lin – структура типа line, n=0 – счётчик человек в комнате, x=1 – переменная для присваивание=я комнатам номера, i=0 – переменная для хода по этажу.
-
s1=s – присваивание для хода по кольцу.
-
Кольцо s пустое, если да, то на шаг 22, иначе 5.
-
Очередь lin пуста, если да, то на шаг 22, иначе 6.
-
Пока очередь lin не пуста выполняются шаги 7-21, иначе 22.
-
Пока очередь lin не пуста и на этаже есть свободные места s1->in.free_bed>0 выполняются шаги 8-19, иначе 22.
-
Пока s1->in.nomb_room[i]!=0 – не найдено свободное место выполняется шаги 9-11, иначе 12.
-
i=i+1, n=n+1 – ход по этажу.
-
Если n>in.bed/s1->in.room–комната пройдена на шаг 10,иначе 8.
-
n=0, x=x+1 – переход на следующую комнату.
-
Запись имени в кольцо s1->in.name[i] из очереди lin->fm.
-
s1->in.free_bed= s1->in.free_bed-1, уменьшение количества свободных мест.
-
n=n+1 – увеличение счётчика человек в комнате.
-
Если n>in.bed/s1->in.room – комната пройдена на шаг 16, иначе 17.
-
n=0, x=x+1 – переход на следующую комнату.
-
s1->in.nomb_room[i]=s1->in.nomb*100+x – номер комнаты.
-
Функция удаление элемента lin из очереди del_line().
-
i=i+1 – переход на следующее место на этаже.
-
s1->in.free_bed==0&&s1->r!=s – этаж полностью заселён, но есть ещё этажи - на шаг 21, иначе 22.
-
i=0, x=1, n=0, s1=s1->r – переход на следующий этаж.
-
Выход
Текст программы:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#define length 20
#define N 4
struct floor
{
Int bed; //количество мест
int free_bed; //количество свободных мест
int room; //количество комнат
int nomb_room[N]; //номер комнаты
char name[N][length]; //имена проживающих
Int nomb; //номер этажа
};
struct ring
{
floor in; //информационное поле
ring *l, *r; //адресные поля
};
struct line
{
char fm[length]; //информационное поле
line *nx; //адресное поле
};
ring *out_file_ring(ring *); //функция считывания из файла
line* add_to_line(line *); //функция добавления в очередь
ring* add_floor(ring *); //функция добавления этажа
line* out_file_line(line *); //функция, которая достаёт из файла очередь
void input_file(ring *, line *); //функция сохранения в файл
line *add_to_ring(ring *, line *); //функция добавления в кольцо из очереди
line* del_line(line *); //функция удаления из очереди
void see(ring *); //функция вывода кольца на экран
void see_line(line *); //функция вывода очереди на экран
floor del(floor, int); //функция удаления студента с этажа
void del_stud(ring *); //функция удаления студента из кольца
void main()
{
ring *s;
line *lin;
int x;
s=NULL;
lin=NULL;
s=out_file_ring(s); //перепись информации из файла в кольцо
lin=out_file_line(lin); //перепись информации из файла в очередь
while(1)
{ system("cls");
printf("0 - exit\n1 - add stud\n2 - save in file\n3 - add floor\n4 - see\n5 - vyselit' studenta\n6 - see line\n");
fflush(stdin);
scanf("%d", &x); //выбор действия
switch(x)
{
case 0: return ; //выход
case 1: lin=add_to_line(lin); //добавление в очередь
lin=add_to_ring(s, lin); //пока есть места в общаге, то добавление в кольцо из очереди
break;
case 2: input_file(s, lin); break; //сохранение информации в файле
case 3: s=add_floor(s); //добавление этажа
if(lin)
lin=add_to_ring(s, lin); //добавление в кольцо из очереди
break;
case 4: see(s); break; //вывод студентов общежития на экран
case 5: del_stud(s); //удаление студенты из общежития
if(lin) //очередь не пуста
lin=add_to_ring(s, lin); break;//добавление в кольцо
case 6: see_line(lin); //вывод очереди на экран
}
}
}
ring *out_file_ring(ring *s)
{
FILE *fl;
ring *s2, *s1;
s2=s1=s;
if(!(fl=fopen("hostel.dat", "rb"))) //открытие файла
{ //для записи из него
puts("\nEror!");
getch();
return 0;
}
if(!s) //кольца нет
{
s=(ring*)calloc(1, sizeof(ring)); //создание первого элемента кольца
s->r=s; //кольцо
s->l=s; //замкнулось
s2=s;
fread(&(s->in), sizeof(floor), 1, fl); //запись из файла в кольцо
}
if(feof(fl)) //файл пустой
{
free(s);
return 0;
}
while (1)
{
s1=(ring*)calloc(1, sizeof(ring));
fread(&(s1->in), sizeof(floor), 1, fl); //запись из файла
if(feof(fl)) //достигнут конец файла
{
free(s1); //удаление последнего элемента
break ;
}
else
{
s2->r=s1; //перекидываем
s1->l=s2; //адреса
s2=s1; //переход на следующий элемент
}
}
s2->r=s; //кольцо
s->l=s2; //замкнулось
fclose(fl); //закрытие файла
return s;
}
line* add_to_line(line *lin)
{
line *lin1, *lin2;
char c;
if(!lin) //очередь пуста
{
lin=(line*) calloc(1, sizeof(line));
fflush(stdin);
printf("Familija:\n");
fflush(stdin);
gets(lin->fm); //запись в очередь первого элемента
}
lin2=lin;
while(1)
{
printf("Ostanovit' vvod? Yes-y\n");
fflush(stdin);
if((c=getchar())=='y')
break;
lin1=(line*) calloc(1, sizeof(line));
printf("Familija:\n");
fflush(stdin);
gets(lin1->fm); //запись в очередь
lin2->nx=lin1;
lin2=lin1;
}
lin2->nx=NULL; //последний элемент очереди
return lin;
}
ring* add_floor(ring *s)
{
int i, x=0, n=0;
char c;
ring *s1, *s2;
if(!s) //если нету кольца
{
s=(ring*)malloc(sizeof(ring)); //создание первого элемента кольца
printf("Vvedite nomer floor: ");
scanf("%d", &(s->in.nomb)); //ввод информации
s->in.bed=s->in.free_bed=N;
s->in.room=2;
s->r=s; //кольцо
s->l=s; //замкнулось
for(i=0;i<N;i++)
s->in.nomb_room[i]=0;
}
s2=s;
while(1)
{
printf("Ostanovit' vvod? Yes-y\n");
fflush(stdin);
if((c=getchar())=='y')
break;
s1=(ring*)malloc(sizeof(ring)); //создание нового элемента кольца
printf("Vvedite nomer floor: ");
scanf("%d", &(s1->in.nomb));
s1->in.bed=s1->in.free_bed=N; //количество мест
s1->in.room=N/2; //количество комнат
s2->r=s1; //перекидывание
s1->l=s2; //адресов
s2=s1;
for(i=0;i<N;i++)
s1->in.nomb_room[i]=0; //присваивание всем комнатам 0-й номер
}
s2->r=s; //кольцо
s->l=s2; //замкнулось
return s;
}
line* out_file_line(line *lin)
{
FILE *fd;
line *lin1, *lin2;
if(!(fd=fopen("line.dat", "rb"))) //открытие файла
{
puts("\nEror!"); //для считывания из него
getch();
return 0;
}
if(!lin&&!feof(fd))
{
lin=(line*)calloc(1, sizeof(line)); //первый элемент очереди
lin->nx=NULL;
fread(&(lin->fm), length*sizeof(char), 1, fd); //считывание из файла
}
if(feof(fd)) //файл пустой
{
free(lin);
fclose(fd);
return 0;
}
lin2=lin;
while(1)
{
{
lin1=(line*)calloc(1, sizeof(line));//новый элемент очереди
lin2->nx=lin1;
fread(&(lin1->fm), length*sizeof(char), 1, fd);//запись из файла
if(feof(fd)) //достигнут конец файла
{
free(lin1);
lin2->nx=NULL;
break;
}
}
}
fclose(fd); //закрытие файла
return lin;
}
void input_file(ring *s, line *lin)
{
FILE *R, *L;
ring *s1;
line *lin1;
s1=s;
if(!(R = fopen("hostel.dat","w+b"))) //открытие файла для записи в него
{
puts("\nEror!");
getch();
return;
}
if(!s) //кольцо отсутствует
{
fclose(R); //закрытие файла
return;
}
do
{
fwrite(&(s1->in), sizeof(floor), 1, R); //запись в файл
s1=s1->r; //переход на следующий элемент кольца
}
while(s1!=s); //пока кольцо не пройдено
fclose(R); //закрытие файла
if(!(L = fopen("line.dat","w+b"))) //открытие файла для записи в него
{
puts("\nОшибка открытия файла!");
getch();
return;
}
if(!lin) //очереди нету
{
fclose(L); //закрытие файла
return; //выход из функции
}
lin1=lin;
while(lin1->nx!=NULL) //пока очередь не пройдена
{
fwrite(&(lin1->fm), length*sizeof(char), 1, L); //запись в файл
lin1=lin1->nx; //переход на следующий элемент очереди
}
fwrite(&(lin1->fm), length*sizeof(char), 1, L); //запись последнего элемента очереди в файл
fclose(L); //закрытие файла
}
line *add_to_ring(ring *s, line *lin)
{
ring *s1;
int n=0, x=1, i=0;
s1=s;
if(!s) //кольцо пусто
return lin;
if(!lin) //очередь пуста
return 0;
while(lin) //пока есть элементы в очереди
{
while((s1->in.free_bed>0)&&lin) //пока есть очередь и есть свободные места
{
while(s1->in.nomb_room[i]!=0)//поиск свободного места
{
i++;
n++;
if(n>s1->in.bed/s1->in.room)//переход на следующую комнату
{
n=0;
x++;
}
}
strcpy(s1->in.name[i], lin->fm); //запись имени в кольцо
s1->in.free_bed-=1; //уменьшение количества свободных мест
n++; //счётчик человек в комнате
if(n>s1->in.bed/s1->in.room) //переход на следующую комнату
{
n=0;
x++;
}
s1->in.nomb_room[i]=s1->in.nomb*100+x;//номер комнаты
lin=del_line(lin); //удаление элемента из очереди
i++;
}
if(s1->in.free_bed==0&&s1->r!=s) //этаж полностью заселён
{
i=0;
s1=s1->r; //переход на следующий этаж
x=1;
n=0;
}
else
return lin;
}
return 0; }
line* del_line(line *lin)
{
if(lin->nx==NULL) //один элемент в очереди
{
free(lin); //удаление элемента
return 0;
}
line *lin2;
lin2=lin;
lin=lin->nx; //переход на следующий элемент очереди
free(lin2); //удаление элемента из очереди
return lin;
}
void see(ring *s)
{
ring *s1;
s1=s;
int i;
do //вывод информации на экран
{
printf("\nFloor number: %d", s1->in.nomb);
printf("\nKolovo mest: %d", s1->in.bed);
printf("\nKolovo svobodn mest: %d", s1->in.free_bed);
printf("\nStudents living here:\n");
printf(" room fm\n");
for(i=0;i<N;i++)
if(s1->in.nomb_room[i]!=0)
{
printf("%21d%21s\n", s1->in.nomb_room[i], s1->in.name[i]);
}
s1=s1->r; //переход на следующий элемент кольца
}
while(s1!=s); //пока не вернулись на первый элемент кольца
}
void see_line(line *lin)
{
line *lin1;
if(!lin)
{
printf("Ochered' pysta!\n");
return ;
}
lin1=lin;
printf("Steidents in line:\n"); //вывод студентов в очереди на заселение
while(lin1)
{
printf("%s\n", lin1->fm);
lin1=lin1->nx; //переход на следующий элемент очереди
}
}
void del_stud(ring *s)
{
ring *s1;
s1=s;
if(!s)
return ;
char st[length];
printf("Vvedite fm dlja ydalenija: ");
fflush(stdin);
gets(st); //ввод студента на выселение
do
{
for(int i=0;i<N;i++) //поиск нужной фамилии в кольце
if(!strcmp(s1->in.name[i], st))
{
s1->in=del(s1->in, i); //удаление студента из общежития
break ;
}
else
if(strcmp(s1->in.name[i], st)&&s1->r==s&&i==N-1)//такого студента нет
printf("Takogo stydenta ne najdeno!\n");
s1=s1->r; //переход на следующий элемент кольца
}
while(s1!=s); //пока кольцо не пройдено
}
floor del(floor in, int i)
{ in.free_bed+=1; //увеличение количество свободных комнат
in.nomb_room[i]=0; //присваивание 0-го номера комнате
in.name[i][0]='\0'; //удаление имени
return in; }