Сохранение (восстановление) базы данных.
Сохранение (восстановление) базы данных. Поскольку в рассматриваемом примере база данных реализована в виде двунаправленного списка в основной памяти и она стирается (ее содержимое исчезает) при завершении работы программы, необходимо предусмотреть как сохранение базы данных во внешней памяти, так и загрузку базы данных из внешней памяти в следующем сеансе работы с ней.
Перед разработкой функции "выгрузка" базы данных в файл на диске необходимо определить формат и состав выгружаемых данных.
Собственно база данных (в виде двух независимых двунаправленных списков - списка занятых элементов и списка свободных элементов) располагается в массиве st структур типа struct person (см. главную программу). Информация о количестве элементов в этих списках, а также указатели на начало и конец списков располагаются в структуре Ctrl типа struct control.
Рассмотрим один из простейших вариантов создания на диске резервной копии базы данных о сотрудниках учреждения. Он состоит в том, что сначала необходимо записать в файл управляющую информацию (содержимое структуры Ctrl), а за ней - весь массив структур (байт за байтом), тем более что в рассматриваемом примере он невелик (7 Кбайт). При восстановлении базы данных из файла на диске читается управляющая информация и размещается в структуре Ctrl, затем читается информация, расположенная в файле за управляющей информацией, и размещается в области основной памяти, отведенной под массив структур st.
Такая схема копирования (восстановления) обладает существенным недостатком: вместе с содержательной информацией в файл записываются и значения указателей (адреса основной памяти), содержащиеся в элементах списков базы данных. Таким образом, при принятой схеме копирования (восстановления) программа обслуживания базы данных будет работать при выполнении условия неизменности адреса загрузки программы в основную память. При работе на персональном компьютере в операционных системах MS-DOS и UNIX (однопользовательский режим) вызванная для выполнения программа будет загружена на то же самое место в основной памяти только в том случае, если между сеансами работы с программой не производились "системные" работы, повлекшие за собой перераспределение основной памяти.
Однако, несмотря на неполную надежность восстановления, приведем исходные тексты функций save( ) - "выгрузить базу данных в файл на диске" и load( ) - "восстановить базу данных из файла". В этих функциях показано, как можно выгрузить (и затем восстановить) из основной памяти в файл на диске содержимое переменных различных типов.
Операция sizeof, примененная в функциях save( ) и load( ), вычисляет длину операнда в байтах. Операторы с = (char *)pti; и с = (char *)ptr; производят явное преобразование указателя pti на целое и указателя ptr на структуру соответственно в указатели на символы, что позволяет использовать последние в качестве аргументов в функциях putc( ) и getc( ) для побайтного обмена с файлом.
В функции save( ) производится запись в файл на диске всех элементов массива структур. Запись производится функцией putc( ) побайтно. Поэтому в программе необходимо описать указатель на символы, т.е. типа char*. Для работы с массивом структур необходим указатель на структуру типа person, содержащую сведения о сотруднике учреждения, и указатель потока, связанный с файлом, в котором производится сохранение базы данных. Назовем этот файл bd.dat.
Приведем текст функции save( ):
Функция load( ) может быть реализована следующим образом:
Перед восстановлением базы данных с диска проверяют, пуст ли список занятых элементов в основной памяти. Если нет, то выдается запрос "Производить загрузку?". В случае неположительного ответа, обозначаемого латинской буквой N или n, загрузка информации в БД из файла не производится.
Для того чтобы программа обслуживания базы данных стала не зависимой от адреса загрузки в основную память, модернизируем функции save() и load() следующим образом:
• будем выгружать (записывать) в файл не весь массив структур, а только список занятых элементов;
• после чтения содержимого файла в массив структур скорректируем значения указателей, образующих связи в связных списках базы данных, т.е. установим реальные адреса в указателях.
На рис. 8.10 показаны состояние списка занятых элементов в массиве структур до выгрузки в файл, структура файла с информацией из базы и состояние массива структур после восстановления базы данных из файла. В общем случае элементы списка, содержащего сведения о сотрудниках, к концу сеанса работы с базой данных могут располагаться не в соседних элементах массива. Однако после выгрузки в файл эти элементы окажутся рядом. Читая из файла в массив структур список занятых элементов байт за байтом, мы размещаем элементы списка с начала массива структур, т.е. элементы списка, в котором хранятся сведения о сотрудниках, в общем случае попадают на новые места в массиве структур, и требуется корректировка адресов в элементах этого списка. Эта процедура аналогична процедуре инициализации массива структур перед началом работы с базой данных. Началом списка свободных элементов будет первый элемент массива структур, не занятый загруженной из файла информацией.
Рис. 8.10. Второй вариант схемы сохранения (восстановления) базы данных
Приведем текст функции save2( ) - "сохранить в файле на диске только список занятых элементов":
Приведем текст функции load2( ) - "загрузить в основную память (прочитать из файла) базу данных из файла с корректировкой адресов, содержащихся в указателях элементов списков базы данных".
В качестве упражнения рекомендуем разработать более надежную схему и формат хранения базы данных и соответствующие функции сохранения (восстановления). В качестве возможного варианта формата хранения базы данных в файле на диске можно использовать следующий:
#1
name=фамилия
dерnаmе=название_отдела
depnumb=код_отдела
price=зарплата
job=код_должности
joname=долукиость
date=дата_приема_на_работу
#2
name=фамшия
где
#1, #2,... - номера записей;
name=, depname=, ... - имена полей в структуре, содержащей сведения о сотрудниках учреждения;
фамилия, название_отдела, ... - содержимое полей структуры в символьном виде.
Файл в таком формате и символьном представлении значений полей структур легко прочитать и модифицировать с помощью любого текстового редактора. Имена полей можно использовать для контроля правильности обработки записи при вводе (см. гл. 7, форматный ввод). Список занятых элементов базы данных формируется в момент ввода данных из файла.
Для того чтобы подготовить программный комплекс к последующей обработке (трансляция, сборка), в простейшем случае необходимо с помощью текстового редактора собрать все функции в один файл (набор данных). Этот файл должен иметь следующую структуру:
• объектов, используемых во вспомогательных функциях (массив структур типа struct person, управляющие переменные в структуре ctrl);
• описание внешних переменных;
• функция main( );
• функция init( );
• функция find( );
• функция fr( );
• функция delete( );
• функция input( );
• функция print( );
• функция save( ) или функция save2( );
• функция load( ) или функция load2( ).
Подробно подготовка программного комплекса для работы с базой данных о сотрудниках учреждения описана в главе 9.
- Предисловие
- Раздел 1. Полный курс программирования на стандартном языке Си Глава 1. Базовые понятия языка
- 1.1. Алфавит, идентификаторы, служебные слова Алфавит
- Идентификатор
- Служебные (ключевые) слова
- 1.2. Константы и строки
- Символы, или символьные константы.
- Целые константы.
- Вещественные константы.
- Предельные значения и типы арифметических констант.
- Целые константы и выбираемые для них типы
- Данные вещественных типов
- Нулевой указатель.
- Строки, или строковые константы.
- 1.3. Переменные и именованные константы Переменная как объект.
- Определение переменных.
- Предельные значения переменных.
- Основные типы данных
- Инициализация переменных.
- Именованные константы.
- 1.4. Операции
- Знаки операций.
- Приоритеты (ранги) операций
- Унарные (одноместные) операции.
- 1.5. Разделители
- Квадратные скобки.
- Круглые скобки.
- Запятая.
- Точка с запятой.
- Двоеточие.
- Многоточие.
- Звездочка.
- Обозначение присваивания.
- Признак препроцессорных средств.
- 1.6. Выражения и приведение арифметических типов
- Отношения и логические выражения.
- Присваивание (выражение и оператор).
- Приведение типов.
- Правила преобразования типов
- Правила стандартных арифметических преобразований
- Выражения с поразрядными операциями.
- Условное выражение.
- Глава 2. Введение в программирование на языке си
- 2.1. Структура и компоненты простой программы
- Текст программы и препроцессор.
- Структура программы.
- Функция форматированного вывода.
- Программы печати предельных констант.
- Применимость вещественных данных.
- Выделение лексем из текста программы.
- 2.2. Элементарные средства программирования Деление операторов языка Си на группы.
- Программа оценки машинного нуля.
- Трассировочная таблица
- Ввод данных.
- Вычисление объема цилиндра.
- Сумма членов ряда Фибоначчи.
- 2.3. Операторы цикла Три формы операторов цикла.
- Приближенное значение экспоненты.
- Оператор break.
- Сумма отрезка степенного ряда.
- Оператор continue.
- Суммирование положительных чисел.
- 2.4. Массивы и вложение операторов цикла Массивы и переменные с индексами.
- Вычисление среднего и дисперсии.
- Упорядочение в одномерных массивах.
- Инициализация массивов.
- 2.5. Функции Определение функций.
- Функция для вычисления объема цилиндра.
- Функция для вычисления скалярного произведения векторов.
- Обращение к функции и ее прототип.
- Вычисление биномиального коэффициента.
- Вычисление объема цилиндра
- Вычисление площади треугольника.
- Скалярное произведение векторов.
- 2.6. Переключатели
- Глава 3. Препроцессорные средства
- 3.1. Стадии и команды препроцессорной обработки
- Стадии препроцессорной обработки.
- Директивы препроцессора.
- 3.2. Замены в тексте Директива #define.
- Цепочка подстановок.
- 3.3. Включение текстов из файлов
- 3.4. Условная компиляция Директивы ветвлений.
- Операция defined.
- 3.5. Макроподстановки средствами препроцессора
- Моделирование многомерных массивов.
- Отличия макросов от функций.
- Препроцессорные операции в строке замещения.
- 3.6. Вспомогательные директивы
- Препроцессорные обозначения строк.
- Реакция на ошибки.
- Пустая директива.
- Прагмы.
- 3.7. Встроенные (заранее определенные) макроимена
- Глава 4. Указатели, массивы, строки
- 4.1. Указатели на объекты Адреса и указатели.
- Операции над указателями.
- Арифметические операции и указатели.
- Указатели и отношения.
- 4.2. Указатели и массивы Указатели и доступ к элементам массивов.
- Массивы динамической памяти.
- Функции для выделения и освобождения памяти
- Массивы указателей и моделирование многомерных массивов.
- "Матрица" со строками разной длины.
- 4.3. Символьная информация и строки
- Ввод-вывод символьных данных.
- Внутренние коды и упорядоченность символов.
- Строки, или строковые константы.
- Строки и указатели.
- Глава 5. Функции
- 5.1. Общие сведения о функциях Определение функции.
- Описание функции и ее тип.
- Вызов функции.
- 5.2. Указатели в параметрах функций Указатель-параметр.
- Имитация подпрограмм.
- 5.3. Массивы и строки как параметры функций Массивы в параметрах.
- Резюме по строкам-параметрам.
- 5.4. Указатели на функции Указатели при вызове функций.
- Указатели на функции как параметры
- Указатель на функцию как возвращаемое функцией значение.
- Библиотечные функции с указателями на функции в параметрах.
- 5.5. Функции с переменным количеством параметров
- Доступ к адресам параметров из списка.
- Макросредства для переменного числа параметров.
- Примеры функций с переменным количеством параметров.
- 5.6. Рекурсивные функции
- 5.7. Классы памяти и организация программ Локализация объектов.
- Глобальные объекты.
- Динамическая память
- Внешние объекты.
- 5.8. Параметры функции main( )
- Глава 6. Структуры и объединения
- 6.1. Структурные типы и структуры Производные типы.
- Структурный тип.
- Определение структур.
- Выделение памяти для структур.
- Инициализация и присваивание структур.
- Доступ к элементам структур.
- 6.2. Структуры, массивы и указатели Массивы и структуры в качестве элементов структур.
- Массивы структур.
- Указатели на структуры.
- Указатели как средство доступа к компонентам структур.
- Указатели на структуры как компоненты структур.
- 6.3. Структуры и функции
- Имитация абстрактных типов данных.
- 6.4. Динамические информационные структуры Статическое и динамическое представление данных.
- Односвязный список.
- Рекурсия при обработке списка.
- 6.5. Объединения и битовые поля Объединения.
- Битовые поля.
- Глава 7. Ввод и вывод
- 7.1. Потоковый ввод-вывод
- 7.1.1. Открытие и закрытие потока
- 7.1.2. Стандартные файлы и функции для работы с ними
- Ввод-вывод отдельных символов.
- Ввод-вывод строк.
- Форматный ввод-вывод.
- Спецификаторы форматной строки для функции форматного вывода
- Спецификаторы форматной строки для функции форматного ввода
- 7.1.3. Работа с файлами на диске
- Двоичный (бинарный) режим обмена с файлами.
- Строковый обмен с файлами.
- Позиционирование в потоке.
- Трехъязычный словарь "Цифры
- 7.2. Ввод-вывод нижнего уровня
- 7.2.1. Открытие / закрытие файла
- 7.2.2. Чтение и запись данных
- 7.2.3. Произвольный доступ к файлу
- Глава 8. Примеры разработки программ
- 8.1. Программа с объектами разных классов памяти Постановка задачи.
- Программная реализация.
- 8.2. Структуры и обработка списков в основной памяти Постановка задачи.
- Функция main( ).
- Функция init( ) - "Инициализировать базу данных".
- Функция delete() - "Удалить все сведения о сотруднике из базы данных".
- Функция fr( ) - "Возвратить освобожденный элемент в список свободных элементов".
- Функция input( ) - "Ввести в базу данных сведения о новом сотруднике".
- Функция print( ) - "Печать списка занятых элементов".
- Сохранение (восстановление) базы данных.
- 8.3. Сортировка на основе бинарного дерева Статические и динамические данные.
- Управление динамической памятью.
- Сортировка с помощью бинарного дерева.
- Печать результатов сортировки.
- Раздел 2. Выполнение программ в разных операционных системах Глава 9. Подготовка и выполнение программ
- 9.1. Подготовка программ в операционной системе unix
- 9.1.1. Команда make
- Формат файла описаний зависимостей модулей.
- Формат команды make.
- Макроопределения.
- Встроенные правила.
- 9.1.2. Библиотеки объектных модулей
- Стандартные библиотеки.
- Создание и сопровождение собственных библиотек.
- 9.2. Сборка и выполнение программ в интегрированной среде Turbo с 2.0
- 9.2.1. Состав системы программирования Turbo с 2.0
- 9.2.2. Экран интегрированной среды Turbo с 2.0
- 9.2.3. Система меню среды Turbo с 2.0
- 9.2.4. Настройка среды Turbo с
- Создание рабочего каталога.
- Установка в среде Turbo с 2.0 полных имен каталогов.
- Настройка параметров управления проектом.
- 9.5. Окно определения проекта
- Сборка и выполнение программы.
- 1. Команды управления курсором:
- 2. Команды вставки и удаления:
- 3. Команды обработки блоков текста:
- 4. Дополнительные команды:
- 9.3.2. Экран интегрированной среды
- 9.3.3. Система меню интегрированной среды
- Задание полных имен основных и рабочего каталогов.
- Выбор стандарта языка Си.
- Установка параметров подсистемы Make.
- Создание проекта.
- Задание аргументов командной строки.
- Сохранение параметров настройки интегрированной среды.
- Сборка и выполнение программы.
- Работа в интегрированной среде в последующих сеансах.
- Раздел 3. Практикум по программированию на языке Си Глава 10. Задачи по программированию
- 10.1. Ознакомительная работа
- 10.2. Итерационные методы и ряды
- Варианты заданий по итерационным методам и рядам
- 10.3. Работа со строками. Указатели, динамические одномерные массивы
- 10..1. Варианты задач по обработке строк*
- 10.3.2. Рекомендации по обработке строк
- 10.3.3. Пример выполнения задания по обработке строк
- 10.4. Многомерные динамические массивы с переменными размерами
- 10.4.1. Варианты задач для 1-й части задания по многомерным массивам (правила формирования многомерного массива)
- 10.4.2. Варианты для 2-й части задания по многомерным массивам
- 10.4.3. Пример выполнения задания по многомерным динамическим массивам
- 10.5. Функции и указатели
- 10.6. Функции и массивы
- 10.7. Работа со структурами
- 10.7.1. Варианты структур для выполнения работы
- 10.8. Списки и деревья
- 10.8.1. Списки
- 10.8.2. Деревья
- Приложение 1. Таблицы кодов ascii
- Коды управляющих символов (0 31)
- Символы с кодами 32 127
- Символы с кодами 128 255 (Кодовая таблица 866 - ms-dos)
- Символы с кодами 128 255 (Кодовая таблица 1251 - ms Windows)
- Приложение 2. Константы предельных значений
- Приложение 3. Стандартная библиотека функций языка Си
- Функции для работы с терминалом в текстовом режиме (файл conio.H)
- Специальные функции
- Литература
- Содержание
- Раздел 1. Полный курс программирования на стандартном языке Си 4
- Глава 1. Базовые понятия языка 4
- Глава 2. Введение в программирование на языке си 33
- Глава 3. Препроцессорные средства 73
- Глава 4. Указатели, массивы, строки 91
- Глава 5. Функции 114
- Глава 6. Структуры и объединения 155
- Глава 7. Ввод и вывод 186
- Глава 8. Примеры разработки программ 218
- Раздел 2. Выполнение программ в разных операционных системах 256
- Глава 9. Подготовка и выполнение программ 256
- Раздел 3. Практикум по программированию на языке Си 282
- Глава 10. Задачи по программированию 282
- Подбельский Вадим Валерьевич Фомин Сергей Сергеевич программирование на языке си
- 101000, Москва, ул. Покровка, 7 Телефон (095) 925-35-02, факс (095) 925-09-57