
- •Лабораторная работа № 6 Реализация списка в двоичном файле
- •Лабораторная работа № 6 Реализация линейного списка в двоичном файле.
- •Теоретические сведения
- •Описание типов для списка, размещаемого в двоичном файле
- •Основные процедуры для реализации списка в двоичном файле
- •Вывод списка на экран;
- •Открытие файла для списка
- •1.1.1Инициализация списка
- •1.1.2Вывод списка на экран
- •1.1.3Поиск физического места для размещения нового элемента в файле
- •1.1.4Освобождение физического места в файле после удаления элемента из списка
- •1.1.5Добавление нового элемента в отсортированный список
- •1.1.6Поиск элемента в отсортированном списке
- •1.1.7Удаление элемента из отсортированного списка
- •1.1.12Реализации основного модуля проекта
- •Задания для выполнения проекта
- •Тестирование проекта
- •Содержание отчета
- •Контрольные вопросы и задания
1.1.1Инициализация списка
Инициализация списка в файле заключается в создании двух заголовочных записей в файле. В поля Next этих записей заносим значения -1 – признак того, что список дыр и список элементов пусты.
Процедура инициализации представлена на рисунке 6.4.
//Функция инициализации файла. void initFile(FILE *&f) { TSStudF newRec; //Запись файла newRec.Next=-1; //Инициализировать файл - значит записать //в начало файла 2 записи с количеством элементов -1. fwrite(&newRec,sizeof(TSStudF),1,f); //Первая запись - заголовок списка "дыр" fwrite(&newRec,sizeof(TSStudF),1,f); //Вторая запись - заголовок списка элементов cout<<"Файл со списком проинициализирован."<<endl; } |
Рисунок 6.4 – Процедура инициализации файла
1.1.2Вывод списка на экран
Для вывода списка на экран будем использовать функцию showList.
Процедура получает файловую переменную и адрес первого элемента списка.
Процедура вывода списка в представлена на рисунке 6.6.
//Функция вывода списка из файла на экран //Параметры:файловая переменная f, //St - смещение(адрес) первого элемента списка void showList(FILE *&f,int St) {TSStudF stud;int WP; if (St==-1) { cout<<"Список пустой"<<endl<<endl; return; }; // Инициализация рабочего "указателя" WP=St; while (WP != -1) { // чтение текущего элемента fseek(f,WP,SEEK_SET); fread(&stud,sizeof(TSStudF),1,f); //вывод текущего элемента cout<<stud.fam<<" "<<stud.bal<<endl; // переход на следующий элемент WP=stud.Next; }; } |
Рисунок 6.6 – Процедура вывода списка из файла на экран
1.1.3Поиск физического места для размещения нового элемента в файле
Процедура поиска физического места для размещения нового элемента в файле выполняет туже задачу, что и процедура new для кучи – возвращает адрес свободного участка памяти, где можно разместить новый элемент. Отличие состоит в том, что процедура new встроенная в язык С++, а для файла необходимо реализовать эту процедуру разработчику.
Поскольку в файле есть список дыр, т.е. список свободных записей, то новый элемент можно разместить в одной из таких «дыр», а не в конце файла. В таком случае будет сэкономлена память на внешнем носителе и размер файла не увеличится.
Процедура поиска физического места в файле получает файловую переменную, а возвращает позицию (номер записи), в которой можно разместить новый элемент.
Алгоритм процедуры следующий:
Проверка поля Next у заголовочной записи списка дыр. Оно может быть равно -1, что означает, что дыр нет или любое другое значение, больше ноля, следовательно, в файле есть свободные записи;
Если список дыр пуст, то процедура возвращает номер записи, следующей, за последней заполненной записью файла. Новый элемент будет дописываться в конец файла;
Если список дыр не пуст, то первая дыра извлекается из списка дыр, а в поле Next заголовочной записи заносится адрес бывшей второй (теперь уже первой) дыры. Номер записи, в которой находится бывшая первая дыра, возвращается в качестве позиции для размещения в ней нового элемента для списка.
Процедура поиска физического места в файле для размещения нового элемента приведена на рисунке 6.6.
//Функция возвращает место записи нового элемента списка //Параметры:файловая переменная f int newPosInFile(FILE *&f) {TSStudF stud;int newPos; struct stat statbuf; //Для получения размера файла // читаем заголовок списка дыр rewind(f); //Указатель на начало файла fread(&stud,sizeof(TSStudF),1,f); if (stud.Next==-1) {// если список дыр пуст fstat(fileno(f),&statbuf); return statbuf.st_size; // то позиция - в конце файла } else // иначе позиция - первая по списку "дыра" { newPos=stud.Next; fseek(f,newPos,SEEK_SET); fread(&stud,sizeof(TSStudF),1,f); rewind(f); // адрес второй "дыры" заносим в заголовочную fwrite(&stud,sizeof(TSStudF),1,f); // запись списка "дыр" return newPos; //Возвращаем место вставки нового элемента в первую "дыру" }; } |
Рисунок 6.6 – Процедура поиска физического места для размещения нового элемента в файле