чтобы избежать утечек памяти, в промежутках между использованием структур regex_t необходимо вызывать функцию regfree().
Всякий раз когда функция regcomp() или regex() возвращает ненулевой результат, функция regerror() может предоставить подробное сообщение, в котором будет указано, в чем состоит ошибка. Она записывает по возможности все сообщение об ошибке в буфер и возвращает размер всего сообщения. Поскольку вы заранее не знаете, какой размер будет иметь сообщение, то сначала вам необходимо узнать его размер, а затем распределить и использовать буфер, как показано в следующем далее примере кода. Поскольку этот вариант обработки ошибок быстро становится устаревшим, и вам придется включать его как минимум дважды (один раз после функции regcomp () и один раз после функции regex()), мы советуем вам написать код собственной оболочки функции regerror(), как показано в строке 10 из листинга math.с.
23.2.3. Простая утилита grep
grep является популярной утилитой, определенной в стандарте POSIX, которая предлагает возможности поиска регулярного выражения в текстовых файлах. Ниже показана простая (не соответствующая стандарту POSIX) версия утилиты grep, реализованная с помощью функций стандартного регулярного выражения.
  1: /* grep.с */
  2:
  3: #include <alloca.h>
  4: #include <ctype.h>
  5: #include <popt.h>
  6: #include <regex.h>
  7: #include <stdio.h>
  8: #include <string.h>
  9: #include <unistd.h>
 10:
 11: #define MODE_REGEXP 1
 12: #define MODE_EXTENDED 2
 13: #define MODE_FIXED 3
 14:
 15: void do_regerror(int errcode, const regex_t *preg) {
 16:  char *errbuf;
 17:  size_t errbuf_size;
 18:
 19:  errbuf_size = regerror(errcode, preg, NULL, 0);
 20:  errbuf = alloca(errbuf_size);
 21:  if (!errbuf) {
 22:   perror('alloca');
 23:   return;
 24:  }
 25:
 26:  regerror(errcode, preg, errbuf, errbuf_size);
 27:  fprintf(stderr, '%s
', errbuf);
 28: }
 29:
 30: int scanFile(FILE * f, int mode, const void * pattern,
 31:  int ignoreCase, const char * fileName,
 32:  int * maxCountPtr) {
 33:  long lineLength;
 34:  char * line;
 35:  int match;
 36:  int rc;
 37:  char * chptr;
 38:  char * prefix = '';
 39:
 40:  if (fileName) {
 41:   prefix = alloca(strlen(fileName) + 4);
 42:   sprintf(prefix, '%s: ', fileName);
 43:  }
 44:
 45:  lineLength = sysconf(_SC_LINE_MAX);
 46:  line = alloca(lineLength);
 47:
 48:  while (fgets(line, lineLength, f) && (*maxCountPtr)) {
 49:   /* если у нас не будет завершающего символа '
'
 50:      то мы не сможем получить всю строку целиком */
 51:   if (line [strlen (line) -1] != '
') {
 52:    fprintf(stderr, ' %s line слишком длинная
', prefix);
 53:    return 1;
 54:   }
 55:
 56:   if (mode == MODE_FIXED) {
 57:    if (ignoreCase) {
 58:     for (chptr = line; *chptr; chptr++) {
 59:      if (isalpha(*chptr)) *chptr = tolower(*chptr);
 60:     }
 61:    }
 62:    match = (strstr(line, pattern) != NULL);
 63:   } else {
 64:    match = 0;
 65:    rc = regexec (pattern, line, 0, NULL, 0);
 66:    if (!rc)
 67:     match = 1;
 68:    else if (rc != REG_NOMATCH)
 69:    do_regerror(match, pattern);
 70:   }
 71:
 72:   if (match) {
 73:    printf('%s%s', prefix, line);
 74:    if (*maxCountPtr > 0)
 75:     (*maxCountPtr)--;
 76:   }
 77:  }
 78:

 
                