25.5. Пример

25.5. Пример

Для закрепления материала этой главы ниже приводится пример приложения, в котором задействовано большинство функциональных возможностей qdbm. Подразумевается, что в результате выполнения этого приложения будет создана простая база данных телефонных номеров, хотя ее можно использовать и для хранения любых простых пар "имя-значение". Приложение хранит базу данных в домашнем каталоге пользователя как .phonedb.

Флаг добавляет запись в базу данных. Если будет указан флаг -f, то любой существующий элемент будет заменен новыми данными. Следующий параметр представляет собой значение ключа, которое необходимо использовать, а последний параметр — собственно данные (номер телефона).

Флаг -q запрашивает в базе данных определенный ключ, который должен быть представлен другим указанным параметром. Записи удаляются из базы данных с помощью флага -d, который принимает значение ключа для удаления в другом параметре.

Если задать флаг -l, то будут перечислены все пары "ключ-значение", имеющиеся в базе данных.

Вот как выглядят пример использования phones.

$ ./phones -a Erik 374-5876

$ ./phones -a Michael 642-4235

$ ./phones -a Larry 527-7976

$ ./phones -a Barbara 227-2272

$ ./phones -q Larry

Larry 527-7976

$ ./phones -l

Larry 527-7976

Erik 374-5876

Michael 642-4235

Barbara 227-2272

$ ./phones -d Michael

$ ./phones -l

Larry 527-7976

Erik 374-5876

Barbara 227-2272

Эта программа выполняет определенные полезные действия, состоит менее чем из 200 строк исходного кода, и с успехом может применяться для работы с большим количеством пар "ключ-значение", четко раскрывая назначение библиотеки qdbm.

  1: /* phones.с */

  2:

  3: /* Программа реализует очень простую базу данных телефонных номеров.

  4: Всю необходимую информацию по ее использованию можно найти в тексте. */

  5:

  6: #include <alloca.h>

  7: #include <depot.h>

  8: #include <errno.h>

  9: #include <fcntl.h>

 10: #include <stdio.h>

 11: #include <stdlib.h>

 12: #include <string.h>

 13: #include <unistd.h>

 14:

 15: void usage(void) {

 16:  fprintf(stderr, "использование: phones -a [-f] <имя> <телефон> ");

 17:  fprintf(stderr, " -d <имя> ");

 18:  fprintf(stderr, " -q <имя> ");

 19:  fprintf(stderr, " -l ");

 20:  exit(1);

 21: }

 22:

 23: /* Открыть базу данных $НОМЕ/.phonedb. Если writeable имеет ненулевое

 24:    значение, база данных открывается для обновления. Если writeable

 25:    равен 0, база данных открывается только для чтения. */

 26: DEPOT * openDatabase(int writeable) {

 27:  DEPOT * dp;

 28:  char * filename;

 29:  int flags;

 30:

 31:  /* Установить режим открытия */

 32:  if (writeable) {

 33:   flags = DP_OWRITER | DP_OCREAT;

 34:  } else {

 35:   flags = DP_OREADER;

 36:  }

 37:

 38:  filename = alloca(strlen(getenv("HOME")) + 20);

 39:  strcpy(filename, getenv("HOME"));

 40:  strcat(filename, "/.phonedb");

 41:

 42:  dp = dpopen(filename, flags, 0);

 43:  if (!dp) {

 44:   fprintf(stderr, "сбой при открытии %s: %s ", filename,

 45:    dperrmsg(dpecode));

 46:   return NULL;

 47:  }

 48:

 49:  return dp;

 50: }

 51:

 52: /* добавить новую запись в базу данных; произвести

 53:    прямой разбор аргументов командной строки */

 54: int addRecord(int argc, char ** argv) {

 55:  DEPOT * dp;

 56:  char * name, * phone;

 57:  int rc = 0;

 58:  int overwrite = 0;

 59:  int flag;

 60:

 61:  /* проверить параметры; -f означает перезапись

 62:     существующего элемента, а имя и номер телефона

 63:     должны оставаться неизмененными */

 64:  if (!argc) usage();

 65:  if (!strcmp(argv[0], " -f")) {

 66:   overwrite = 1;

 67:   argc--, argv++;

 68:  }

 69:

 70:  if (argc! = 2) usage();

 71:

 72:  name = argv[0];

 73:  phone = argv[1];

 74:

 75:  /* открыть базу данных для записи */

 76:  if (!(dp = openDatabase(1))) return 1;

 77:

 78:  /* если не перезаписывается существующий элемент,

 79:     проверить, не используется ли уже это имя */

 80:  if (!overwrite) {

 81:   flag = DP_DKEEP;

 82:  } else {

 83:   flag = DP_DOVER;

 84:  }

 85:

 86:  if (!dpput(dp, name, -1, phone, -1, flag)) {

 87:   if (dpecode == DP_EKEEP) {

 88:    fprintf(stderr, "%s уже существует ", name);

 89:   } else {

 90:    fprintf(stderr, "сбой записи: %s ", dperrmsg(dpecode));

 91:   }

 92:

 93:   rc = 1;

 94:  }

 95:

 96:  dpclose(dp);

 97:

 98:  return rc;

 99: }

100:

101: /* найти имя и вывести номер телефона, с которым оно связано;

102:    напрямую разобрать командную строку */

103: int queryRecord(int argc, char ** argv) {

104:  DEPOT * dp;

105:  int rc;

106:  char * phone;

107:

108:  /* ожидается только один аргумент, имя для поиска */

109:  if (argc != 1) usage();

110:

111:  /* открыть базу данных для чтения */

112:  if (!(dp = openDatabase(0))) return 1;

113:

114:  phone = dpget(dp, argv[0], -1, 0, -1, NULL);

115:  if (!phone) {

116:   if (dpecode == DP_ENOITEM)

117:    fprintf(stderr, "%s не существует ", argv[0]);

118:   else

119:    fprintf(stderr, "ошибка чтения базы данных: %s "

120:     dperrmsg(dpecode));

121:

122:   rc = 1;

123:  } else {

124:   printf("%s %s ", argv[0], (char *) phone);

125:   rc = 0;

126:  }

127:

128:  dpclose(dp);

129:

130:  return rc;

131: }

132:

133: /* удалить определенную запись; имя передается в качестве

134:    аргумента командной строки */

135: int delRecord(int argc, char ** argv) {

136:  DEPOT * dp;

137:  int rc;

138:

139:  /* ожидается только один аргумент */

140:  if (argc != 1) usage();

141:

142:  /* открыть базу данных для обновления */

143:  if (!(dp = openDatabase(1))) return 1;

144:

145:  if (!(rc = dpout(dp, argv[0], -1))) {

146:   if (dpecode == DP_ENOITEM)

147:    fprintf(stderr, "%s не существует ", argv[0]);

148:   else

149:    fprintf(stderr, "ошибка удаления элемента: %s ",

150:     dperrmsg(dpecode));

151:

152:   rc = 1;

153:  }

154:

155:  dpclose(dp);

156:

157:  return rc;

158: }

159:

160: /* вывести список всех записей, имеющихся в базе данных */

161: int listRecords(void) {

162:  DEPOT * dp;

163:  char * key, * value;

164:

165:  /* открыть базу данных только для чтения */

166:  if (!(dp = openDatabase(0))) return 1;

167:

168:  dpiterinit(dp);

169:

170:  /* итерация по всем записям */

171:  while ((key = dpiternext(dp, NULL))) {

172:   value = dpget(dp, key, -1, 0, -1, NULL);

173:   printf("%s %s ", key, value);

174:  }

175:

176:  dpclose(dp);

177:

178:  return 0;

179: }

180:

181: int main(int argc, char ** argv) {

182:  if (argc == 1) usage();

183:

184:  /* найти флаг режима и вызвать соответствующую функцию

185:     с остальными аргументами */

186:  if (!strcmp(argv[1], "-а"))

187:   return addRecord(argc - 2, argv + 2);

188:  else if (!strcmp(argv[1], "-q"))

189:   return queryRecord(argc - 2, argv + 2);

190:  else if (!strcmp(argv[1], "-d"))

191:   return delRecord(argc - 2, argv + 2);

192:  else if (!strcmp(argv[1], "-l")) {

193:   if (argc != 2) usage();

194:   return listRecords();

195:  }

196:

197:  usage(); /* не обнаружено никаких параметров */

198:  return 0; /* возврат */

199: }

Поделитесь на страничке

Следующая глава >

Похожие главы из других книг

Пример

Из книги Обработка событий в С++ автора Клюев Александр

Пример В примере создаются два класса обработчик и инициатор события, устанавливается связь между ними и иллюстрируется обработка события в нескольких объектах одновременно:#include "stdafx.h" #include "sigslot.h"struct EventRaiser { // источник события signal<const char*> event; // const char* – тип аргумента.


25.5. Пример

Из книги Разработка приложений в среде Linux. Второе издание автора Джонсон Майкл К.

25.5. Пример Для закрепления материала этой главы ниже приводится пример приложения, в котором задействовано большинство функциональных возможностей qdbm. Подразумевается, что в результате выполнения этого приложения будет создана простая база данных телефонных номеров,


27.1.1. Пример

Из книги Искусство программирования на языке сценариев командной оболочки автора Купер Мендель

27.1.1. Пример В главе 8 был представлен пример использования обычной разделяемой библиотеки. Библиотеку libhello.so, которую нам удалось создать, можно загружать во время выполнения. Программа loadhello загружает libhello.so динамически и вызывает функцию print_hello, которая находится в


Пример 10-27. Простой пример сравнения строк

Из книги Программирование для Linux. Профессиональный подход автора Митчелл Марк

Пример 10-27. Простой пример сравнения строк #!/bin/bash# match-string.sh: простое сравнение строкmatch_string (){ MATCH=0 NOMATCH=90 PARAMS=2 # Функция требует два входных аргумента. BAD_PARAMS=91 [ $# -eq $PARAMS ] || return $BAD_PARAMS case "$1" in "$2") return $MATCH;; * ) return $NOMATCH;; esac}a=oneb=twoc=threed=twomatch_string $a # неверное число


Пример 12-20. Пример форматирования списка файлов в каталоге

Из книги UNIX: разработка сетевых приложений автора Стивенс Уильям Ричард

Пример 12-20. Пример форматирования списка файлов в каталоге #!/bin/bash# За основу сценария взят пример "man column".(printf "PERMISSIONS LINKS OWNER GROUP SIZE DATE TIME PROG-NAME " ; ls -l | sed 1d) | column -t# Команда "sed 1d" удаляет первую строку, выводимую командой ls,#+ (для локали "С" это строка: "total N",#+ где "N" -- общее


Пример 12-45. Пример работы с m4

Из книги UNIX — универсальная среда программирования автора Пайк Роб

Пример 12-45. Пример работы с m4 #!/bin/bash# m4.sh: Демонстрация некоторых возможносией макропроцессора m4# Строкиstring=abcdA01echo "len($string)" | m4 # 7echo "substr($string,4)" | m4 # A01echo "regexp($string,[0-1][0-1],&Z)" | m4 # 01Z# Арифметикаecho "incr(22)" | m4 # 23echo "eval(99 / 3)" | m4 #


Пример 24-2. Еще один пример проверки аргументов с помощью "И-списков"

Из книги автора

Пример 24-2. Еще один пример проверки аргументов с помощью "И-списков" #!/bin/bashARGS=1 # Ожидаемое число аргументов.E_BADARGS=65 # Код завершения, если число аргументов меньше ожидаемого.test $# -ne $ARGS && echo "Порядок использования: `basename $0` $ARGS аргумент(а)(ов)" && exit $E_BADARGS# Если


Пример 25-8. Пример реализации алгоритма Решето Эратосфена

Из книги автора

Пример 25-8. Пример реализации алгоритма Решето Эратосфена #!/bin/bash# sieve.sh# Решето Эратосфена# Очень старый алгоритм поиска простых чисел.# Этот сценарий выполняется во много раз медленнее# чем аналогичная программа на C.LOWER_LIMIT=1 # Начиная с 1.UPPER_LIMIT=1000 # До 1000.# (Вы можете


9.4. Пример

Из книги автора

9.4. Пример В архитектуре x86 есть инструкции, определяющие позицию старшего и младшего значащих битов в слове. Процессор выполняет эти инструкции очень быстро. С другой стороны, чтобы сделать то же самое на языке С, потребуется написать цикл с операциями побитового


Пример

Из книги автора

Пример В листинге 11.1[1] показана простая программа, вызывающая функцию gethostbyname для любого числа аргументов командной строки и выводящая всю возвращаемую информацию.Листинг 11.1. Вызов функции и вывод возвращаемой информации//names/hostent.c 1 #include "unp.h" 2 int 3 main(int argc, char **argv) 4 { 5  char


Пример

Из книги автора

Пример Сначала приведем пример с Ipv4:freebsd % traceroute www.unpbook.comtraceroute to www.unpbook.com (206.168.112.219): 30 hops max. 24 data bytes1 12.106.32.1 (12.106.32.1) 0.799 ms 0.719 ms 0.540 ms2 12.124.47.113 (12.124.47.113) 1.758 ms 1.760 ms 1.839 ms3 gbr2-p27.sffca.ip.att.net (12.123.195.38) 2.744 ms 2.575 ms 2.648 ms4 tbr2-p012701.sffca.ip.att.net (12.122.11.85) 3.770 ms 3.689 ms 3.848 ms5 gbr3-p50.dvmco.ip.att.net (12.122.2.66) 26.202 ms 26.242 ms


Пример

Из книги автора

Пример Сначала мы запустим нашу программу с аргументом командной строки -0 и убедимся, что сервер имен отвечает на приходящие дейтаграммы, не содержащие контрольной суммы. Мы также задаем флаг -v.macosx # udpcksum -i en1 -0 -v bridget.rudoff.com domaindevice = en1local net = 172.24.37.64. netmask = 255.255.255.224cmd = udp and src host