Сейчас заново вы создадите приложение, использующее базу данных dbm для хранения нужной вам информации, в виде файлов cd_data.h, app_ui.c и cd_access.c (упражнения 7.14–7.16).
Вы также перепишите пользовательский интерфейс в виде программы с вводом команд. Позже в этой книге интерфейс базы данных и части пользовательского интерфейса будут пересмотрены, когда будет рассматриваться реализация вашего приложения с помощью различных клиент-серверных механизмов и затем как приложения, к которому можно обращаться по сети, используя Web-обозреватель. Преобразование интерфейса в более простой строковый интерфейс
позволит сосредоточиться не на нем, а на более важных частях приложения.
Примечание
В последующих главах вы не раз встретитесь с заголовочным файлом базы данных cd_data.h и функциями из файла cd_access.c. Помните о том, что некоторые дистрибутивы Linux требуют немного отличающихся формирующих опций, например, применения в вашем файле на языке С заголовочного файла gdbm-ndbm.h вместо файла ndbm.h и опций
– lgdbm_compat -lgdbm
вместо просто опции
– lgdbm
. Если в вашем дистрибутиве Linux дело обстоит именно так, вы должны внести соответствующие изменения в файлы access.с и Makefile.
Упражнение 7.14. Файл cd_data.h
Начните с заголовочного файла для определения структуры ваших данных и подпрограмм, которые будут использоваться для доступа к данным.
1. Далее приведено определение структуры данных для базы данных компакт-дисков. В него включено определение структур и размеров двух таблиц, формирующих базу данных. Начните с задания размеров некоторых полей, которые вы будете применять, и двух структур: одной для элемента каталога, а другой для элемента дорожки.
/* Таблица catalog */
#define CAT_CAT_LEN 30
#define CAT_TITLE_LEN 70
#define CAT_TYPE_LEN 30
#define CAT_ARTIST_LEN 70
typedef struct {
char catalog[CAT_CAT_LEN + 1];
char title[CAT_TITLE_LEN + 1];
char type [CAT_TYPE_LEN + 1];
char artist[CAT_ARTIST_LEN + 1];
} cdc_entry;
/* Таблица дорожек, по одному элементу на дорожку */
#define TRACK_CAT_LEN CAT_CAT_LEN
#define TRACK_TTEXT_LEN 70
typedef struct {
char catalog[TRACK_CAT_LEN + 1];
int track_no;
char track_txt[TRACK_TTEXT_LEN + 1];
} cdt_entry;
2. Теперь, имея структуры данных, можно определить нужные вам подпрограммы доступа. Функции с префиксом
cdc_
в имени предназначены для элементов каталога, с префиксом
cdt_
— для элементов-дорожек.
Примечание
Учтите, что некоторые функции возвращают структуры данных. Вы можете указать на аварийное
завершение таких функций, сделав содержимое структур пустым.
Теперь перейдем к пользовательскому интерфейсу. Вам предлагается простая программа, с помощью которой вы сможете обращаться к функциям вашей базы данных. Интерфейс реализуется в отдельном файле.
1. Как обычно, начните с некоторых заголовочных файлов:
#define _XOPEN_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include "cd_data.h"
#define TMP_STRING_LEN 125 /* это число должно быть больше
самой длинной строки в структуре базы данных */
2. Опишите пункты вашего меню с помощью
typedef
. Этот вариант лучше применения констант, заданных в директивах
#define
, т.к. позволяет компилятору проверить типы переменных, задающих пункт меню.
typedef enum {
mo_invalid,
mo_add_cat,
mo_add_tracks,
mo_del_cat,
mo_find_cat,
mo_list_cat_tracks,
mo_del_tracks,
mo_count_entries,
mo_exit
} menu_options;
3. Теперь введите прототипы локальных функций. Помните о том, что прототипы функций, обеспечивающих реальный доступ к базе данных, включены в файл cd_data.h.