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

12.2.4. Поиск байта с данным значением: memchr()

12.2.4. Поиск байта с данным значением: memchr()

Функция memchr() сходна с функцией strchr(): она возвращает местоположение определенного значения внутри произвольного буфера. Как и в случае memcmp() против strcmp(), основной причиной для использования memchr() является использование произвольных двоичных данных.

GNU wc использует memchr() при подсчете лишь строк и байтов[124], и это позволяет быть быстрой. Из wc.c в GNU Coreutils:

257  else if (!count_chars && !count_complicated)
258  {
259   /* Использует отдельный цикл при подсчете лишь строк или строк и байтов -
260      но не символов или слов. */
261  while ((bytes_read = safe_read(fd, buf, BUFFER_SIZE)) > 0)
262  {
263   register char *p = buf;
264
265   if (bytes_read == SAFE_READ_ERROR)
266   {
267    error(0, errno, "%s", file);
268    exit_status = 1;
269    break;
270   }
271
272   while ((p = memchr(p, 'n', (buf + bytes_read) - p)))
273   {
274    ++p;
275    ++lines;
276   }
277   bytes += bytes_read;
278  }
279 }

Внешний цикл (строки 261–278) читает блоки данных из входного файла. Внутренний цикл (строки 272–276) использует memchr() для поиска и подсчета символов конца строки. Сложное выражение '(buf + bytes_read) - р' сводится к числу оставшихся байтов между текущим значением p и концом буфера.

Комментарии в строках 259–260 нуждаются в некотором объяснении. Вкратце, современные системы могут использовать символы, занимающие более одного байта в памяти и на диске. (Это несколько более подробно обсуждается в разделе 13.4 «Не могли бы вы произнести это для меня по буквам?».) Таким образом, wc должна использовать другой код, если она различает байты и символы: этот код имеет дело со случаем подсчета байтов.

Оглавление книги


Генерация: 1.154. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз