cdc_entry search_cdc_entry(const char *cd_catalog_ptr,
int *first_call_ptr);
Упражнение 7.15. Файл app_ui.c
Теперь перейдем к пользовательскому интерфейсу. Вам предлагается простая программа, с помощью которой вы сможете обращаться к функциям вашей базы данных. Интерфейс реализуется в отдельном файле.
1. Как обычно, начните с некоторых заголовочных файлов:
#define _XOPEN_SOURCE
#include
#include
#include
#include
#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.
static int command_mode(int argc, char *argv[]);
static void announce(void);
static menu_options show_menu(const cdc_entry *current_cdc);
static int get_confirm(const char *question);
static int enter_new_cat_entry(cdc_entry *entry_to_update);
static void enter_new_track_entries(const cdc_entry* entry_to_add_to);
static void del_cat_entry(const cdc_entry *entry_to_delete);
static void del_track_entries(const cdc_entry *entry_to_delete);
static cdc_entry find_cat(void);
static void list_tracks(const cdc_entry *entry_to_use);
static void count_all_entries(void);
static void display_cdc(const cdc_entry *cdc_to_show);
static void display_cdt(const cdt_entry *cdt_to_show);
static void strip_return(char *string_to_strip);
4. И наконец, вы добрались до функции main
. Она начинается с проверки того, что текущий элемент current_cdc_entry
, который применяется для сохранения дорожки выбранного в данный момент элемента каталога компакт-дисков, инициализирован. Также проводится грамматический разбор командной строки, выдается оповещение о том, какая программа выполняется, и инициализируется база данных.
void main(int argc, char *argv[]) {
menu_options current_option;
cdc_entry current_cdc_entry;
int command_result;
memset(¤t_cdc_entry, '\0', sizeof(current_cdc_entry));
if (argc >1) {
command_result = command_mode(argc, argv);
exit(command_result);
}
announce();
if (!database_initialize(0)) {
fprintf(stderr, "Sorry, unable to initialize database\n");
fprintf(stderr, "To create a new database use %s -i\n", argv[0]);
exit(EXIT_FAILURE);
}
5. Теперь вы готовы обрабатывать ввод пользователя. Вы остаетесь в цикле, запрашивая пункт меню и обрабатывая его до тех пор, пока пользователь не выберет выход. Обратите вниманий на то, что вы передаете структуру current_cdc_entry
в функцию show_menu
, чтобы разрешить изменять варианты пунктов меню, когда выбран текущий элемент каталога:
while (current_option != mo_exit) {
current_option = show_menu(¤t_cdc_entry);
switch(current_option) {
case mo_add_cat:
if (enter_new_cat_entry(¤t_cdc_entry)) {
if (!add_cdc_entry(current_cdc_entry)) {
fprintf(stderr, "Failed to add new entry\n");
memset(¤t_cdc_entry, '\0',
sizeof(current_cdc_entry));
}
}
break;
case mo_add_tracks:
enter_new_track_entries(¤t_cdc_entry);
break;
case mo_del_cat:
del_cat_entry(¤t_cdc_entry);
break;
case mo_find_cat:
current_cdc_entry = find_cat();
break;
case mo_list_cat_tracks:
list_tracks(¤t_cdc_entry);
break;
case mo_del_tracks:
del_track_entries(¤t_cdc_entry);
break;
case mo_count_entries:
count_all_entries();
break;
case mo_exit:
break;
case mo_invalid:
break;
default:
break;
} /* switch */
} /* while */
6. Когда цикл в функции main
завершится, закройте базу данных и вернитесь в окружение. Функция announce
выводит приглашающее предложение:
database_close();
exit(EXIT_SUCCESS);
} /* main */
static void announce(void) {
printf("\n\nWelcome to the demonstration CD catalog database \
program\n");
}
7. Здесь вы реализуете функцию show_menu
. Эта функция проверяет, выбран ли текущий элемент каталога, используя первый символ имени в каталоге. Если элемент каталога выбран, становятся доступными дополнительные пункты меню:
Читать дальше