
Министерство образования Республики Беларусь
Учреждение образования
«Полоцкий государственный университет»
Кафедра технологий программирования
КОНТРОЛЬНАЯ РАБОТА
Вариант 19
По курсу: «Программирование»
(1 семестр)
8 вариант
Группа 11-КБ
Выполнил Бегунов С.В.
Проверила Кеда И.С.
Полоцк, 2011
Условие задачи:
Описание структуры: содержит информацию о музыкальных композициях, выходящих в эфир: исполнитель (строка 20 символов), наименование (строка 30 символов), продолжительность (в минутах), дата и время выхода в эфир (дд.мм.гггг чч:мм). Формат ввода/вывода:
«НАЗВАНИЕ» «ИСПОЛ-ТЕЛЬ» ПРОДОЛЖ. ДД.ММ.ГГГГ ЧЧ:ММ
Дополнительная обработка: Удалить из списка все записи, в которых дата выхода в эфир лежит в определенном диапазоне.
Проектирование программы
Программа разбита на следующие модули:
List;
Sort;
Main;
Data.
Модуль List
Модуль List хранит в себе структуру двунаправленного списка, а так же реализует следующие внешние функции:
Add - добавление записи в конец списка,
Ins - вставка записи в середину списка,
Del - удаление записи из списка,
MoveHead, MoveNext, MovePrev - перемещение по списку,
Sort - сортировка списка,
Save - сохранение списка в файл,
Load - загрузка списка из файла,
Destroy - удаление всего списка,
Init – инициализация списка,
OrderedIns – вставка введённой записи в нужную позицию,
Set – установка значения в текущую позицию,
Get – получения значения из текущей позиции,
Show – вывод списка на экран,
Process – удаление элементов списка по параметру.
Модуль Sort
Модуль Sort хранит основную структуру данных:
name – название песни,
sing – имя исполнителя,
min, sec – продолжительность песни,
day, month, year – дата выхода в эфир,
hour, minutes – время выхода в эфир.
А так же функции сравнения по полю или группе полей, чтение элементов одной записи и запись элементов в 1 строку:
CmpName – сравнение по названию песни,
CmpSing – сравнение по имени исполнителя,
CmpLong – сравнение по продолжительности песни,
CmpDate – сравнение по дате выхода в эфир,
CmpTime – сравнение по времени выхода в эфир,
ParseFromStr – функция чтения новых записей,
ToStr – функция записи полей одного элемента в строку.
Модуль Main
Это главный модуль программы, в нём заложен алгоритм действий и вызовы функций других модулей. Собственных функций он не имеет.
Модульная схема изображена в приложении 1.
Реализация программы Реализация модуля List
Add – функция добавления элемента в конец двунаправленного списка. В качестве параметров получает указатель на структуру списка и указатель на новый элемент. возвращает 1 - в случае выполнения, 0 - в случае ошибки.
int Add(LIST *ls, const SONG *val)
{
Element *tmp = (Element *)malloc(sizeof(Element));
if(!tmp) return 0;
if(!ls->head){
ls->head=tmp; tmp->prev=NULL; tmp->next=NULL;
}else{
if(!ls->curr) ls->curr=ls->head;
while(ls->curr->next) ls->curr=ls->curr->next;
ls->curr->next=tmp;
tmp->prev=ls->curr;
tmp->next=NULL;
}
tmp->val = *val; ls->curr=tmp;
return 1;
}
Ins – функция вставки элемента в текущую позицию. В качестве параметров получает указатель на структуру списка и указатель на новый элемент. возвращает 1 - в случае выполнения, 0 - в случае ошибки.
int Ins(LIST *ls, const SONG *val)
{
if(!ls->curr) return Add(ls,val);
Element * tmp=(Element *)malloc(sizeof(Element));
if(!tmp) return 0;
tmp->next=ls->curr;
tmp->prev=ls->curr->prev;
ls->curr->prev=tmp;
if(tmp->prev) tmp->prev->next=tmp;
else ls->head=tmp;
tmp->val = *val;
ls->curr = tmp;
return 1;
}
Del – функция удаления элемента из списка. В качестве параметра получает указатель на структуру списка. возвращает 1 - в случае выполнения, 0 - в случае ошибки.
int Del(LIST *ls)
{
if(ls->curr==NULL) return 0;
Element *tmp=ls->curr;
ls->curr = tmp->next;
if(tmp->prev) tmp->prev->next = ls->curr;
if(tmp->next) tmp->next->prev = tmp->prev;
if(ls->head == tmp) ls->head = tmp->next;
free(tmp);
return 1;
}
Функции для перемещения по списку:
Перемещение на предыдущий элемент(MovePrev):
int MovePrev(LIST *ls)
{
if((ls->curr == NULL)||(ls->curr->prev==NULL)) return 0;
ls->curr = ls->curr->prev;
return 1;
}
Перемещение на следующий элемент(MoveNext):
int MoveNext(LIST *ls)
{
if((ls->curr == NULL)||(ls->curr->next==NULL)) return 0;
ls->curr = ls->curr->next;
return 1;
}
Перемещение в начало списка(MoveHead):
int MoveHead(LIST *ls)
{
ls->curr = ls->head;
if(ls->head == NULL) return 0;
return 1;
}
Sort – функция сортировки списка вставками. В параметраф получает указатель на список, способ сортировки и указатель на функцию сортировки. Фунция ничего не не возвращает.
void Sort(LIST *ls, int dir, int (*cmp)(const SONG *,const SONG *))
{
Element *tmp, *cur;
if(! ((dir==1)||(dir==-1))) return;
if((!ls->head)||(!ls->head->next)) return;
ls->curr = ls->head->next;
while(ls->curr){
tmp = ls->curr;
cur = ls->curr->prev;
ls->curr = ls->curr->next;
cur->next = tmp->next;
if(tmp->next) tmp->next->prev = cur;
while(cur&&(dir*cmp(&cur->val,&tmp->val) > 0)) cur = cur->prev;
if(cur){
tmp->next = cur->next;
tmp->prev = cur;
cur->next = tmp;
if(tmp->next) tmp->next->prev = tmp;
}else{
tmp->next = ls->head;
tmp->prev = NULL;
ls->head->prev = tmp;
ls->head = tmp;
}
}
ls->curr = ls->head;
}
Save – сохранения элементов списка в файл. В параметрах получает указатель на список и имя файла. Возвращает 1 – в случае сохранения, 0 – в случае ошибки.
int Save(LIST *ls, const char *name)
{
FILE *F = fopen(name,"wb");
if(!F) return 0;
Element *tmp = ls->head;
while(tmp){
if(1 != fwrite(&tmp->val,sizeof(SONG),1,F)){
fclose(F);
return 0;
}
tmp = tmp->next;
}
fclose(F);
return 1;
}
Load – функция загрузки элементов из бинарного файла в двунаправленный список. В качестве параметров получает указатель на структуру двунаправленного списка и переменную, содержащую имя загружаемого файла. Возвращает 1 - в случае выполнения, 0 - в случае ошибки.
int Load(LIST *ls, const char *name)
{
FILE *F = fopen(name,"rb");
if(!F) return 0;
fseek(F,0,2);
int sz = ftell(F);
rewind(F);
if(sz%sizeof(SONG) != 0) return 0;
int N = sz/sizeof(SONG);
LIST tmp = {NULL,NULL};
for(int i=0;i<N;i++){
SONG val;
if(1 != fread(&val,sizeof(SONG),1,F)){
Destroy(&tmp);
fclose(F);
return 0;
}
if(!Add(&tmp,&val)){
Destroy(&tmp);
fclose(F);
return 0;
}
}
Destroy(ls);
fclose(F);
*ls = tmp;
return 1;
}
Destroy – функция удаляет весь список. В качестве параметров принимает указатель на список. Ничего не возвращает.
void Destroy(LIST *ls)
{
while(ls->head != NULL){
ls->curr = ls->head;
ls->head = ls->head->next;
free(ls->curr);
}
ls->curr = NULL;
}
Init – функция инициализирует структуру списка.
void Init(LIST *ls)
{
ls->head = ls->curr = NULL;
}
OrderedIn – функция вставляет новую запись в список согласно сортировке. В качестве параметров в неё передаётся указатель на список, новый элемент списка, тип сортировки и указатель на функцию сортировки. В качестве возвращаемого значения она передаёт функцию вставки элемента в текущую позицию.
int OrderedIns(LIST *ls, const SONG *val, int dir, int (*cmp)(const SONG *,const SONG *))
{
if(ls->head == NULL) return Add(ls,val);
ls->curr = ls->head;
while(ls->curr){
if(dir*cmp(&ls->curr->val,val) < 0)
return Ins(ls,val);
ls->curr = ls->curr->next;
}
return Add(ls,val);
}
Show – функция выводит список в консоль.
void Show(const LIST *ls)
{
Element *tmp = ls->head;
int cnt = 1;
while(tmp){
char str[100];
ToStr(str,&tmp->val);
printf("%s\n",str);
if(cnt%20 == 0){
puts("Press any key to continue!");
_getch();
}
cnt++;
tmp = tmp->next;
}
}
Process – функция удаляет элементы, лежащие в определённом отрезке времени. В функцию передаются: указатель на список, концы промежутка времени и имя файла, в который необходимо записать удалённые элементы.
void Process(LIST *ls,unsigned Syear, unsigned Smonth, unsigned Sday, unsigned Fyear, unsigned Fmonth, unsigned Fday, const char *name)
{
FILE *R = NULL;
if(name[0]!=0) R = fopen(name,"wt");
ls->curr = ls->head;
while(ls->curr){
if(ls->curr->val.year>=Syear &&
ls->curr->val.month>=Smonth &&
ls->curr->val.day>=Sday &&
ls->curr->val.year<=Fyear &&
ls->curr->val.month<=Fmonth &&
ls->curr->val.day<=Fday){
if(R != NULL){
char str[150];
ToStr(str,&ls->curr->val);
fprintf(R,"%s\n",str);
}
Del(ls);
}else ls->curr = ls->curr->next;
}
if(R != NULL) fclose(R);
}