Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Запросы к базе данных компакт-дисков




Теперь рассмотрим функции для доступа к данным, которые для упрощения доступа хранятся в паре простых файлов как поля, разделенные запятыми.

1. Страстным коллекционерам важно знать, каким богатством они обладают или сколько собрано. Следующая функция делает это превосходно; она просматривает базу данных, подсчитывая заголовки и дорожки.

void count_cds() {

FILE *titles_fp, *tracks_fp;

char entry[MAX_ENTRY];

int titles = 0;

int tracks = 0;

titles_fp = fopen(title_file, "r");

if (titles_fp) {

while (fgets(entry, MAX_ENTRY, titles_fp))

titles++;

fclose(titles_fp);

}

tracks_fp = fopen(tracks_file, "r");

if (tracks_fp) {

while (fgets(entry, MAX_ENTRY, tracks_fp))

tracks++;

fclose(tracks_fp);

}

mvprintw(ERROR_LINE, 0,

"Database contains %d titles, with a total of %d tracks.", titles, tracks);

get_return();

}

2. Вы потеряли аннотацию к вашему любимому компакт-диску? Не волнуйтесь! Если вы аккуратно ввели подробную информацию в базу данных, теперь можно найти перечень дорожек с помощью функции

find_cd

. Она предлагает ввести подстроку, совпадение с которой нужно искать в базе данных, и устанавливает в глобальную переменную

current_cd

заголовок найденного компакт-диска.

void find_cd() {

char match[MAX_STRING], entry[MAX_ENTRY];

FILE *titles_fp;

int count = 0;

char *found, *title, *catalog;

mvprintw(Q_LINE, 0, "Enter a string to search for in CD titles: ");

get_string(match);

titles_fp = fopen(title_file, "r");

if (titles_fp) {

while (fgets(entry, MAX_ENTRY, titles_fp)) {

/* Пропускает прежний номер в каталоге */

catalog = entry;

if (found == strstr(catalog, ", ")) {

*found = '\0';

title = found + 1;

/* Стирает следующую запятую в элементе, укорачивая его

только до заголовка */

if (found == strstr(title, ", ")) {

*found = '\0';

/* Теперь проверяет, есть ли совпадающая строка */

if (found == strstr(title, match)) {

count++;

strcpy(current_cd, title);

strcpy(current_cat, catalog);

}

}

}

}

fclose(titles_fp);

}

if (count!= 1) {

if (count == 0) {

mvprintw(ERROR_LINE, 0, "Sorry, no matching CD found. ");

}

if (count > 1) {

mvprintw(ERROR_LINE, 0,

"Sorry, match is ambiguous: CDs found. ", count);

}

current_cd[0] = '\0';

get_return();

}

}

Хотя переменная

catalog

указывает на массив, больший чем

current_cat

, и могла бы переписать память, проверка в функции

fgets

препятствует этому.

3. Вам также нужно иметь возможность перечислить на экране дорожки выбранного компакт-диска. Для вложенных окон можно использовать директивы

#define

, применявшиеся в функции

update_cd

в предыдущем разделе.

void list_tracks() {

FILE *tracks_fp;

char entry[MAX_ENTRY];

int cat_length;

int lines_op = 0;

WINDOW *track_pad_ptr;

int tracks = 0;

int key;

int first_line = 0;

if (current_cd[0] == '\0') {

mvprintw(ERROR_LINE, 0, "You must select a CD first. ");

get_return();

return;

}

clear_all_screen();

cat_length = strlen(current_cat);

/* Сначала считает количество дорожек у текущего CD */

tracks_fp = fopen(tracks_file, "r");

if (!tracks_fp) return;

while (fgets(entry, MAX_ENTRY, tracks_fp)) {

if (strncmp(current_cat, entry, cat_length) == 0) tracks++;

}

fclose(tracks_fp);

/* Создает новую панель, гарантируя, что даже при наличии одной

дорожки панель достаточна большая, поэтому последующий вызов

prefresh() всегда будет допустим. */

track_pad_ptr = newpad(tracks + 1 + ВОХЕD_LINES, BOXED_ROWS + 1);

if (!track_pad_ptr) return;

tracks_fp = fopen(tracks_file, "r");

if (!tracks_fp) return;

mvprintw(4, 0, "CD Track Listing\n");

/* Записывает сведения о дорожке на панель */

while (fgets(entry, MAX_ENTRY, tracks_fp)) {

/* Сравнивает номер каталога и оставшийся вывод элемента */

if (strncmp(current_cat, entry, cat_length) == 0) {

mvwprintw(track_pad_ptr, lines_op++, 0, "%s", entry + cat_length + 1);

}

}

fclose(tracks_fp);

if (lines_op > BOXED_LINES) {

mvprintw(MESSAGE_LINE, 0,

"Cursor keys to scroll, RETURN or q to exit");

} else {

mvprintw(MESSAGE_LINE, 0, "RETURN or q to exit");

}

wrefresh(stdscr);

keypad(stdscr, TRUE);

cbreak();

noecho();

key = 0;

while (key!= "q" && key!= KEY_ENTER && key!= '\n') {

if (key == KEY_UP) {

if (first_line > 0) first_line--;

}

if (key == KEY_DOWN) {

if (first_line + BOXED_LINES + 1 < tracks) first_line++;

}

/* Теперь рисует соответствующую часть панели на экране */

prefresh(track_pad_ptr, first_line, 0, BOX_LINE_POS, BOX_ROW_POS,

BOX_LINE_POS + BOXED_LINES, BOX_ROW_POS + BOXED_ROWS);

key = getch();

}

delwin(track_pad_ptr);

keypad(stdsсr, FALSE);

nocbreak();

echo();

}

4. В последних двух функциях вызывается функция

get_return

, которая приглашает к вводу и считывает символ возврата каретки, игнорируя другие символы.

void get_return() {

int ch;

mvprintw(23, 0, "is", " Press return ");

refresh();

while ((ch = getchar())!= '\n' && ch!= EOF);

}

Если вы выполните эту программу, то увидите на экране нечто похожее на рис. 6.10.

Рис. 6.10

Резюме

В этой главе вы изучили библиотеку curses. Она предлагает текстовым программам удобный способ управления экраном и считывания данных с клавиатуры. Хотя библиотека curses не обеспечивает такого уровня управления, как общий терминальный интерфейс (GTI) и прямой доступ к структуре

terminfo

, ею гораздо легче пользоваться. Если вы пишете полноэкранное текстовое приложение, стоит рассмотреть возможность применения в нем библиотеки curses для управления экраном и чтения данных с клавиатуры.

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...