Чтение онлайн

на главную

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

34

35 unsigned long myrandom(void)

36 {

37 static int fd = -1;

38 unsigned long data;

39

40 if (fd == -1)

41 fd = open("/dev/urandom", O_RDONLY);

42

43 if (fd == -1 || read(fd, &data, sizeof data) <= 0)

44 return random; /* отступить */

45

46 return data;

47 }

48

49 /* main ---
вывести N различных граней кубиков */

50

51 int main(int argc, char **argv)

52 {

53 int nfaces;

54 int i, j, k;

55

/* ...проверка args, вычисление nfaces, как ранее... */

68

69 for (i = 1; i <= nfaces; i++) {

70 j = myrandom % 6; /* обеспечить диапазон 0 <= j <= 5 */

71 printf("+-------+\n");

72 for (k = 0; k < 3; k++)

73 printf("|%s|\n", die_faces[(j * 3) + k]);

74 printf("+-------+\n");

75 putchar('\n');

76 }

77

78 return 0;

79 }

Строки 35–47 предоставляют интерфейс вызова функции для

/dev/urandom
, читая каждый раз данные
unsigned long
. Издержками является один дескриптор файла, который остается открытым в течение жизни программы.

12.7. Расширения метасимволов

Три набора функции возрастающей сложности предусматривают возможность сопоставления с шаблонами групповых символов оболочки. Многим программам нужны такие библиотечные функции. Одним примером является

find
: '
find .
– name '*.с' -print
'. Другим примером является опция
– -exclude
во многих программах, которая принимает шаблон файлов с групповыми символами для исключения из того или иного действия. В данном разделе по очереди рассматривается каждый набор функций.

12.7.1. Простое сопоставление с шаблоном:

fnmatch

Мы начинаем с функции

fnmatch
(«filename match» сопоставление имени файла»).

#include <fnmatch.h> /* POSIX */

int fnmatch(const char *pattern, const char *string, int flags);

Эта функция сопоставляет

string
с
pattern
, который является обычным шаблоном групповых символов оболочки. Значение флагов (которое вскоре будет описано) изменяет поведение функции. Возвращаемое значение равно 0, если
string
соответствует
pattern
,
FNM_NOMATCH
, если не соответствует, и ненулевое значение, если возникла ошибка. К сожалению, POSIX не определяет каких-либо специфических ошибок; соответственно, вы можете лишь сказать, что что-то пошло не так, но не можете сказать, что.

Переменная

flags
является побитовым ИЛИ одного или более флагов, перечисленных в табл. 12.1.

Таблица 12.1. Значения флагов для

fnmatch

Флаг Только GLIBC Значение
FNM_CASEFOLD
Сопоставление
с учетом регистра
FNM_FILE_NAME
Синоним GNU для
FNM_PATHNAME
FNM_LEADING_DIR
Флаг для внутреннего использования GLIBC; не используйте его в своих программах. Подробности см. в fnmatch(3)
FNM_NOESCAPE
Обратный слеш является обычным символом, а не знаком перехода
FNM_PATHNAME
Слеш в
string
должен соответствовать слешу в
pattern
, он не может быть подставлен через
*
,
?
или '
[...]
'
FNM_PERIOD
Начальная точка в
string
подходит, лишь если в
pattern
также есть начальная точка. Точка должна быть первым символом в
string
. Однако, если также установлен
FNM_PATHNAME
, точка, которая идет за слешем, также рассматривается как начальная

fnmatch
работает со строками из любого источника; сопоставляемые строки не обязательно должны быть действительными именами файлов. Хотя на практике
fnmatch
используется в коде, читающем каталог с помощью
readdir
(см раздел 5.3.1 «Базовое чтение каталогов»):

struct dirent dp;

DIR *dir;

char pattern[100];

/* ...заполнить шаблон, открыть каталог, проверить ошибки... */

while ((dp = readdir(dir)) != NULL) {

 if (fnmatch(pattern, dir->d_name, FNM_PERIOD) == 0)

/* имя файла соответствует шаблону */

 else

continue; /* не соответствует */

}

GNU

ls
использует
fnmatch
для реализации своей опции
– -ignore
. Вы можете предоставить несколько игнорируемых шаблонов (с помощью нескольких опций).
ls
сопоставляет каждое имя файла со всеми шаблонами. Она делает это с помощью функции
file_interesting
в
ls.с
:

2269 /* Возвращает не ноль, если файл в 'next' должен быть перечислен. */

2270

2271 static int

2272 file_interesting(const struct dirent *next)

2273 {

2274 register struct ignore_pattern* ignore;

2275

2276 for (ignore = ignore_patterns; ignore; ignore = ignore->next)

2277 if (fnmatch(ignore->pattern, next->d_name, FNM_PERIOD) == 0)

Поделиться:
Популярные книги

Элита элит

Злотников Роман Валерьевич
1. Элита элит
Фантастика:
боевая фантастика
8.93
рейтинг книги
Элита элит

Купеческая дочь замуж не желает

Шах Ольга
Фантастика:
фэнтези
6.89
рейтинг книги
Купеческая дочь замуж не желает

Большая игра

Ланцов Михаил Алексеевич
4. Иван Московский
Фантастика:
альтернативная история
5.00
рейтинг книги
Большая игра

Он тебя не любит(?)

Тоцка Тала
Любовные романы:
современные любовные романы
7.46
рейтинг книги
Он тебя не любит(?)

Отмороженный

Гарцевич Евгений Александрович
1. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный

Смерть может танцевать 2

Вальтер Макс
2. Безликий
Фантастика:
героическая фантастика
альтернативная история
6.14
рейтинг книги
Смерть может танцевать 2

Я Гордый Часть 3

Машуков Тимур
3. Стальные яйца
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я Гордый Часть 3

70 Рублей

Кожевников Павел
1. 70 Рублей
Фантастика:
фэнтези
боевая фантастика
попаданцы
постапокалипсис
6.00
рейтинг книги
70 Рублей

Болотник 2

Панченко Андрей Алексеевич
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Болотник 2

Измена. Жизнь заново

Верди Алиса
1. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Жизнь заново

Флеш Рояль

Тоцка Тала
Детективы:
триллеры
7.11
рейтинг книги
Флеш Рояль

Кодекс Крови. Книга Х

Борзых М.
10. РОС: Кодекс Крови
Фантастика:
фэнтези
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга Х

Идеальный мир для Лекаря 11

Сапфир Олег
11. Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 11

Брачный сезон. Сирота

Свободина Виктория
Любовные романы:
любовно-фантастические романы
7.89
рейтинг книги
Брачный сезон. Сирота